Python爬取Indeed网站重复返回旧结果及变量未定义问题求助
问题排查与代码修复
1. 爬新职位返回旧结果的问题
核心原因
- HTTP缓存干扰:
requests默认会复用连接,服务器可能返回缓存的旧页面,导致你看到的还是之前的会计职位数据 - 文件名固定导致混淆:原代码写死了CSV文件名
dataanalyst.csv,如果之前的会计数据没被正确覆盖,打开文件时会误以为是新爬的结果
解决办法
- 在请求时添加禁用缓存的HTTP头,强制服务器返回最新页面
- 动态生成CSV文件名,根据职位和地点命名,避免不同爬取任务的数据互相覆盖
2. "records未定义"的错误
核心原因
原代码中保存CSV的代码缩进错误,位于main函数外部,但records是main内部的局部变量,外部代码根本访问不到它,所以报错。
解决办法
把保存CSV的代码缩进,放到main函数内部,确保它能读取到records变量。
修复后的完整代码
# 导入所需库 import csv import requests from datetime import datetime from bs4 import BeautifulSoup # 生成Indeed职位搜索URL def get_url(position, location): template = 'https://www.indeed.com/jobs?q={}&l={}' url = template.format(position, location) return url # 从单条职位卡片提取数据 def get_record(card): # 提取职位标题 job_title = card.h2.a.span.get('title') # 提取职位详情链接 job_url = 'https://indeed.com' + card.h2.a.get('href') # 提取公司名称 company = card.find('span', 'companyName').text.strip() # 提取工作地点 job_location = card.find('div', 'companyLocation').text.strip() # 提取职位摘要 summary = card.find('div', 'job-snippet').text.strip() # 提取发布日期 posted_date = card.find('span', 'date').text.strip() # 记录抓取日期 extract_date = datetime.today().strftime('%Y-%m-%d') # 提取薪资(无薪资时返回空字符串) try: salary = card.find('div', 'metadata estimated-salary-container').text.strip() except AttributeError: salary = '' return (job_title, company, job_location, posted_date, extract_date, summary, salary, job_url) # 主爬取函数 def main(position, location): records = [] url = get_url(position, location) while True: # 添加请求头,禁用缓存+模拟浏览器,避免被反爬或拿到旧数据 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', 'Cache-Control': 'no-cache', 'Pragma': 'no-cache' } response = requests.get(url, headers=headers) soup = BeautifulSoup(response.text, 'html.parser') # 定位所有职位卡片 job_cards = soup.find_all('div', 'job_seen_beacon') for card in job_cards: record = get_record(card) records.append(record) # 处理分页,获取下一页链接 next_btn = soup.find('a', {'aria-label': 'Next'}) if next_btn: url = 'https://indeed.com' + next_btn.get('href') else: break # 动态生成文件名,避免覆盖旧数据 filename = f"{position.replace(' ', '_')}_{location.replace(' ', '_')}.csv" # 保存数据到CSV with open(filename, 'w', newline='', encoding='utf-8') as f: writer = csv.writer(f) # 表头和返回的元组顺序严格对应,避免数据错位 writer.writerow(['职位标题', '公司名称', '工作地点', '发布日期', '抓取日期', '职位摘要', '薪资', '职位链接']) writer.writerows(records) # 执行爬取(示例:远程数据分析师) if __name__ == '__main__': main('data analyst', 'remote')
额外提醒
- 原代码的表头顺序和
record元组的顺序不匹配,已经修正,避免数据错位 - 添加了
User-Agent模拟浏览器,降低被Indeed反爬限制的概率 - 分页逻辑做了优化,判断更严谨,避免无限循环
内容的提问来源于stack exchange,提问作者Salma Dodin
相关产品推荐
相关产品推荐

