You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.25 17:57:19