爬取GlassDoor职位信息返回403状态码,求助排查原因
GlassDoor爬取返回403状态码的原因分析与解决办法
核心原因
- 请求头未伪装:
requests.get默认的User-Agent是python-requests/x.x.x,这种标识会被GlassDoor的反爬机制直接识别为爬虫,返回403拦截。LinkedIn的反爬逻辑相对宽松,所以相同代码能正常运行。 - 会话验证缺失:GlassDoor会检查请求的会话状态,直接单次请求没有提前建立会话(获取必要Cookie),容易被判定为异常请求。
- 类名动态变化:你代码中使用的
JobCard_jobCardContent__X81Ew这类带随机后缀的类名,是GlassDoor前端动态生成的,可能已经更新,导致无法匹配到元素。 - 动态内容渲染:GlassDoor的职位卡片很多是通过JavaScript动态加载的,静态请求直接拿不到渲染后的HTML内容。
解决步骤与代码示例
1. 伪装请求头+维持会话
先通过模拟浏览器请求头,并用Session维持会话,模拟正常用户的访问流程:
import requests from bs4 import BeautifulSoup # 模拟Chrome浏览器的请求头 headers = { 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/118.0.0.0 Safari/537.36', 'Accept-Language': 'en-US,en;q=0.9', 'Referer': 'https://www.glassdoor.com/' } # 建立会话,先访问首页获取Cookie session = requests.Session() session.get('https://www.glassdoor.com', headers=headers) # 请求目标职位页面 url = "https://www.glassdoor.com/Job/united-states-it-entry-level-jobs-SRCH_IL.0,13_IN1_KO14,28.html" response = session.get(url, headers=headers) print(f"请求状态码: {response.status_code}") if response.status_code == 200: soup = BeautifulSoup(response.content, 'html.parser') # 注意:需要用浏览器开发者工具重新查看当前的职位卡片类名 job_listings = soup.find_all('div', class_='jobCard') if job_listings: print(f"找到{len(job_listings)}个职位卡片") for listing in job_listings: # 同样需要确认当前的职位标题类名 job_title = listing.find('a', class_='JobCard_jobTitle') if job_title: print(job_title.get_text(strip=True)) else: print("未匹配到职位卡片,可能内容是JS动态加载的") else: print(f"请求被拦截,状态码: {response.status_code}")
2. 处理动态渲染内容
如果上述方法返回200但仍拿不到职位数据,说明内容是JS动态生成的,需要用浏览器自动化工具模拟加载:
from selenium import webdriver from selenium.webdriver.common.by import By from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.support import expected_conditions as EC # 初始化Chrome浏览器 driver = webdriver.Chrome() driver.get("https://www.glassdoor.com/Job/united-states-it-entry-level-jobs-SRCH_IL.0,13_IN1_KO14,28.html") try: # 等待10秒,直到职位卡片加载完成 WebDriverWait(driver, 10).until( EC.presence_of_element_located((By.CLASS_NAME, "jobCard")) ) # 获取所有职位卡片 job_cards = driver.find_elements(By.CLASS_NAME, "jobCard") for card in job_cards: # 获取职位标题 job_title = card.find_element(By.CLASS_NAME, "JobCard_jobTitle") print(job_title.text.strip()) finally: # 关闭浏览器 driver.quit()
额外注意事项
- 类名更新:GlassDoor会频繁更新前端类名,每次爬取前务必用浏览器开发者工具(F12)查看最新的元素类名。
- 频率控制:即使伪装成功,也要控制请求频率,避免短时间内大量请求触发更严格的反爬(比如IP封禁)。
- Cookie有效期:如果频繁出现403,可以手动在浏览器中登录GlassDoor,复制Cookie到请求头中,提升请求成功率。
内容的提问来源于stack exchange,提问作者Gannan307
相关产品推荐
相关产品推荐

