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

Python使用requests-html爬取网页提取数据随机出现AttributeError怎么办

错误原因

你遇到的报错本质是find方法未匹配到对应元素时返回了None,直接调用.text属性触发空对象属性异常。随机报错的核心诱因有3个:

  • Google Shopping页面为动态渲染,默认渲染时长不足会导致部分节点未加载完成
  • 部分商品报价行本身无对应价格节点
  • 不同商品页的价格标签类名存在动态调整的情况,你加的全局延迟没有作用在渲染等待环节,所以无法解决问题

修复方案

1. 调整渲染参数,确保动态节点加载完整

给render方法添加sleep参数指定渲染后等待时长,同时拉长超时阈值避免渲染中断:

r.html.render(sleep=2, timeout=20)

2. 节点提取前添加非空校验

提取价格节点时先判断是否匹配成功,匹配失败可以赋值默认值或者直接跳过当前异常行:

preis_elem = article.find('div.drzWO', first=True)
# 匹配失败跳过当前行
if not preis_elem:
    continue
preis = preis_elem.text

如果需要保留无价格的行,可以替换为:

preis = preis_elem.text if preis_elem else '价格未公示'

3. 添加备选选择器提升兼容性

可以补充多个价格相关的选择器做兜底,避免类名动态变化导致匹配失败:

preis_elem = article.find('div.drzWO', first=True) or article.find('span.sh-price__current', first=True)

4. 添加请求头规避反爬

Google Shopping会拦截无标识的爬虫请求,返回异常页面导致节点匹配失败,请求时添加浏览器UA即可:

headers = {
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36'
}
r = session.get(url, headers=headers)

修复后完整代码

from requests_html import HTMLSession
import csv
import time

# csv_file = open('beoscrape.csv', 'w', encoding='utf-8-sig')
# csv_writer = csv.writer(csv_file)
# csv_writer.writerow(['Produkt', 'Retailer', 'Preis'])

session = HTMLSession()
headers = {
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36'
}
url = 'https://www.google.com/shopping/product/16302210309954970571/offers?q=OLED+65+G19+LA&newwindow=1&prds=cid:16302210309954970571,eto:856723695612861771_0,scoring:tp'

r = session.get(url, headers=headers)
# 渲染后等待2秒,超时时间设为20秒
r.html.render(sleep=2, timeout=20)

produktscan = r.html.find('title')
produkt = produktscan[0].text
produkt = produkt.replace(' | Google Shopping', '')

for article in r.html.find('tr.sh-osd__offer-row'):
    retailer_elem = article.find('div.kPMwsc', first=True)
    if not retailer_elem:
        continue
    retailer = retailer_elem.full_text
    retailer = retailer.replace('Wird in einem neuen Fenster geöffnet', '').strip()
    
    # 价格节点非空校验+兜底选择器
    preis_elem = article.find('div.drzWO', first=True) or article.find('span[class*="price"]', first=True)
    if not preis_elem:
        continue
    preis = preis_elem.text.strip()

    print(produkt)
    print(retailer)
    print(preis)
    print('-'*30)

#    csv_writer.writerow([produkt, retailer, preis])

# csv_file.close()

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.03 12:36:03