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

Python爬取Indeed职位页 页数设为3时报'NoneType'无find属性错误

报错核心原因

你遇到的'NoneType' object has no attribute 'find'错误是三类问题叠加导致的:

  • 分页URL拼接逻辑完全错误:循环爬取多页时,你写的分页偏移量是固定值nopa*10,无论循环到第几页,请求的都是同一个地址,根本没实现翻页。当nopa设为3时,高频重复请求同一地址极易触发Indeed反爬机制。
  • 没有做基础反爬适配:代码用requests默认请求头发送请求,User-Agent会被识别为python-requests/版本号,平台很容易判定为爬虫。前2页请求没触发风控时能正常返回内容,第3页请求被拦截,返回验证码/访问拦截页,页面里不存在id为mosaic-provider-jobcards的职位列表容器,soup.find()返回None,在None值上调用.find('ul')就会抛出该错误。
  • 节点遍历没有做类型和空值校验:
    1. BeautifulSoup解析时,标签之间的换行、空白内容会被识别为NavigableString类型的文本节点,这类节点没有find方法,你直接遍历ul下所有子节点(包含空白文本节点)调用find,也会触发报错。
    2. 部分职位详情页的描述容器类名存在动态调整,或者请求失败返回异常页面时,查找职位描述div的操作会返回None,直接遍历None同样会触发同类错误。
修复方案

按以下规则调整代码即可正常爬取:

  • 添加模拟浏览器的请求头,降低被反爬拦截的概率
  • 修正分页偏移量逻辑,用循环变量计算分页参数,实现真正翻页
  • 所有find操作后增加空值判断,禁止对None值调用方法
  • 遍历标签子节点时过滤空白文本节点,只处理有效标签节点
  • 每次请求后增加随机延时,避免请求频率过高触发风控

修复后的可运行代码:

import time
import random
from bs4 import BeautifulSoup, Tag
import requests
import matplotlib.pyplot as plt
import pandas as pd

keywordlist = []
keywords = ["PYTHON", "JAVA", "SQL", "NOSQL", "MONGODB", "CASSANDRA",
            "AWS", "AZURE", "SPARK", "AIRFLOW", "HIVE", "HADOOP", "REDSHIFT",
            "S3", "KAFKA", "TABLEAU", "EXCEL", "QLIK", "POWER BI",
            "DYNAMODB", "WAREHOUS", "ALTERYX", "LAKE", "ETL", "CI/CD", "BASH",
            "SHELL"]

occurences = []
tags = []
nopa = 3
# 模拟浏览器请求头
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"
}

for i in range(nopa):
    # 修正分页参数,Indeed分页偏移量为0、10、20...
    url = f"https://de.indeed.com/jobs?q=data%20engineer&start={i*10}&vjk=144c9cb8990a7fc2"
    response = requests.get(url, headers=headers)
    soup = BeautifulSoup(response.text, 'lxml')

    outer_most_point = soup.find('div', attrs={'id': 'mosaic-provider-jobcards'})
    # 容器不存在时跳过当前页,避免报错
    if not outer_most_point:
        time.sleep(random.uniform(2,4))
        continue
    ul_tag = outer_most_point.find('ul')
    if not ul_tag:
        time.sleep(random.uniform(2,4))
        continue
    # 过滤非标签类型的空白节点
    for job in ul_tag.children:
        if not isinstance(job, Tag):
            continue
        point = job.find("a")
        if point is not None and point.get("href"):
            tags.append(point["href"])
    # 随机延时降低反爬触发概率
    time.sleep(random.uniform(1,3))

for tag in tags:
    url_href = 'https://de.indeed.com' + tag
    response = requests.get(url_href, headers=headers)
    soup2 = BeautifulSoup(response.text, 'html.parser')
    desc_div = soup2.find('div', {'class': 'jobsearch-jobDescriptionText'})
    # 职位描述不存在时跳过当前职位
    if not desc_div:
        time.sleep(random.uniform(2,4))
        continue
    # 直接提取整段描述文本做匹配,避免遍历子节点的异常
    desc_text = desc_div.text.upper()
    keywordsublist = []
    for keyword in keywords:
        if keyword in desc_text:
            keywordsublist.append(keyword)
    keywordlist.extend(list(set(keywordsublist)))
    time.sleep(random.uniform(1,2))

for keyword in keywords:
    occurences.append(keywordlist.count(keyword))

df = pd.DataFrame(list(zip(keywords, occurences)), columns=['Technology', 'num'])
df = df[df.num != 0]
df = df.sort_values('num')

plt.bar('Technology', 'num', data=df, color='blue')
plt.xticks(rotation=45)
plt.tight_layout()
plt.show()

内容的提问来源于stack exchange,提问作者user19338164

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 14:21:13