使用requests模块爬取Indeed职位标题遇403错误的解决咨询
解决Indeed爬取403错误并获取职位标题
问题描述
尝试使用requests模块抓取Indeed网站的摩托车机械师职位标题(搜索链接:https://www.indeed.com/jobs?q=motorcycle%20mechanic&l=New%20York%2C%20NY),但运行代码始终返回403状态码,已尝试的代码如下:
import requests from bs4 import BeautifulSoup link = "https://www.indeed.com/jobs" params={ 'q': 'motorcycle mechanic', 'l': 'New York, NY' } headers = { 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/103.0.0.0 Safari/537.36', } def get_job_titles(url): res = requests.get(url,params=params,headers=headers) soup = BeautifulSoup(res.text,"lxml") link_list = [] for item in soup.select("#mosaic-jobResults td.resultContent h2 > a > span[id^='jobTitle']"): link_list.append(item.get("href")) return link_list if __name__ == '__main__': for title in get_job_titles(link): print(title)
解决方法
403状态码是网站反爬机制拦截了请求,可从以下几点调整代码:
- 完善请求头:仅
User-Agent不足以模拟真实浏览器,需补充Accept、Accept-Language等常见字段,让请求更贴近正常用户行为 - 使用会话保持Cookies:先访问Indeed首页获取初始Cookies,再发起搜索请求,避免被识别为爬虫
- 修正元素选择逻辑:原代码错误尝试获取
href,实际需提取span的文本内容,同时调整选择器适配页面结构
修改后的代码
import requests from bs4 import BeautifulSoup import time # 初始化会话,保持Cookies一致性 session = requests.Session() base_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': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8', 'Accept-Language': 'en-US,en;q=0.5', 'Referer': 'https://www.indeed.com/', 'DNT': '1', 'Connection': 'keep-alive', 'Upgrade-Insecure-Requests': '1', } # 先访问首页获取初始Cookies session.get('https://www.indeed.com/', headers=base_headers) time.sleep(1) # 添加短延迟,模拟用户行为 def get_job_titles(): search_url = "https://www.indeed.com/jobs" params = { 'q': 'motorcycle mechanic', 'l': 'New York, NY' } res = session.get(search_url, params=params, headers=base_headers) # 检查请求状态 if res.status_code != 200: print(f"请求失败,状态码:{res.status_code}") return [] soup = BeautifulSoup(res.text, "lxml") job_titles = [] # 定位职位标题元素,过滤无效标签 for item in soup.select("h2.jobTitle > span"): if item.get("id") and item.get("id").startswith("jobTitle"): title_text = item.get_text(strip=True) if title_text: job_titles.append(title_text) return job_titles if __name__ == '__main__': titles = get_job_titles() if titles: print("抓取到的职位标题:") for idx, title in enumerate(titles, 1): print(f"{idx}. {title}") else: print("未抓取到任何职位标题")
额外注意事项
- 不要频繁发起请求,建议每次请求后添加
time.sleep(2-3)的延迟,避免IP被封禁 - Indeed页面结构可能随时更新,需定期检查元素选择器是否有效
- 若需大规模爬取,建议使用代理IP池分散请求来源
内容的提问来源于stack exchange,提问作者robots.txt
相关产品推荐
相关产品推荐

