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

BS4爬取网页报'NoneType' object has no attribute 'find'错误

问题根因

你代码报错是几个问题叠加导致的:

  • 评分提取行语法错误:book.find("div", class_="a-icon-row").find("a", class_="a-link-normal")(["title"])属于错误写法,相当于把find返回的标签对象当函数调用、传入列表参数,会直接抛出TypeError。
  • 未配置请求头触发亚马逊反爬:默认requests的请求头会被亚马逊直接识别为爬虫,返回人机验证页/错误页,此时你写的图书列表容器根本不存在,后续所有find操作都会返回None,再调用text、find等方法就会抛出'NoneType' object has no attribute 'xxx'错误。
  • 定位逻辑鲁棒性极差:用next_sibling.next_sibling.next_sibling链式调用取价格的写法非常脆弱,网页里的换行、空白文本节点都会导致sibling偏移,只要DOM结构有微小变动就会定位失败;同时部分图书条目本身缺失评分、价格字段,无空值判断的链式调用必然报错。
  • 硬编码动态混淆类名:你用的_cDEzb_grid-row_3Cywl这类类名是亚马逊前端打包时自动生成的混淆类名,随时会随版本迭代变更,不适合作为核心定位依据。
修正后代码
import requests
from bs4 import BeautifulSoup

# 模拟真实浏览器请求头,绕过基础反爬
headers = {
    "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/126.0.0.0 Safari/537.36",
    "Accept-Language": "en-IN,en;q=0.9"
}

try:
    resp = requests.get(
        "https://www.amazon.in/gp/bestsellers/books/1318158031/ref=zg_bs_nav_books_1",
        headers=headers
    )
    resp.raise_for_status()
    soup = BeautifulSoup(resp.text, "html.parser")

    # 用稳定的id属性定位所有图书条目,避免依赖动态类名
    books = soup.find_all("div", id="gridItemRoot")
    for book in books:
        # 逐字段做非空判断,避免单条数据缺失中断整个爬取
        # 提取排名
        rank_tag = book.find("span", class_="zg-bdg-text")
        rank = rank_tag.text.strip("#").strip() if rank_tag else "无排名"

        # 提取书名
        name_tag = book.find("div", class_="zg-grid-general-faceout").find("div", class_=lambda c: c and "line-clamp" in c)
        book_name = name_tag.text.strip() if name_tag else "无书名"

        # 提取作者
        author_tag = book.find("div", class_="a-row a-size-small")
        author = author_tag.text.strip() if author_tag else "无作者信息"

        # 提取评分
        rating_tag = book.find("span", class_="a-icon-alt")
        rating = rating_tag.text.strip() if rating_tag else "暂无评分"

        # 提取价格,弃用next_sibling链式写法,直接定位价格标签
        price_tag = book.find("span", class_="p13n-sc-price")
        price = price_tag.text.strip() if price_tag else "暂无价格"

        print(f"排名:{rank} | 书名:{book_name} | 作者:{author} | 评分:{rating} | 价格:{price}")

except Exception as e:
    # 打印完整错误栈方便排查
    import traceback
    traceback.print_exc()
爬取注意事项
  • 不要用多层next_sibling/previous_sibling做元素定位,BS4会把标签之间的换行、空白字符识别为独立的文本节点,非常容易出现定位偏移,优先用元素固定的id、功能类名定位。
  • 爬取亚马逊这类有成熟反爬机制的站点,必须携带真实浏览器的请求头,仅用默认requests配置大概率会被拦截。
  • 所有字段提取必须加非空判断,电商页面的商品条目经常出现字段缺失的情况,直接对None值调用方法/属性必然触发错误。
  • 尽量不要用_cDEzb_开头的混淆类名做定位依据,这类类名随前端发版随时会变,优先选择zg-bdg-text、p13n-sc-price这类长期稳定的功能类名。
  • 标签属性获取的正确写法是tag["属性名"]或者tag.get("属性名"),不要写成函数调用的形式。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 15:57:14