使用BeautifulSoup爬取weather.com天气数据时报AttributeError错误如何解决
报错根因
你遇到的AttributeError: 'NoneType' object has no attribute 'find'报错,直接原因是 soup.find("div",{"class":"locations-title ten-day-page-title"}) 这行代码执行后返回了None,也就是BeautifulSoup没有在页面内容里匹配到你写的对应类名的div节点,对None调用find方法就会触发该报错。
匹配不到节点的常见原因如下:
- 目标网站的前端页面结构已更新,你参考的旧教程里的
locations-title ten-day-page-title、twc-table等类名早已废弃,和当前页面实际节点类名不匹配 - 请求没有携带浏览器UA标识,被网站反爬策略拦截,返回的是异常的反爬页面/空白内容,不存在对应的天气数据节点
- 采用
html.parser解析器容错率较低,部分不规范的HTML结构无法正常解析,导致节点丢失
排查&解决步骤
- 先添加请求头伪装正常浏览器访问,避免被反爬拦截
import requests from bs4 import BeautifulSoup # 替换为你自己浏览器的UA,可直接搜索"我的UA"获取 headers = { "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36" } url = "https://weather.com/en-IE/weather/tenday/l/bf217d537cc1c8074ec195ce07fb74de3c1593caa6033b7c3be4645ccc5b01de" page = requests.get(url, headers=headers) # 先验证请求是否正常 if page.status_code != 200: print(f"请求异常,状态码:{page.status_code}") exit() - 验证返回的页面内容是否正确
可以把返回的HTML内容存到本地文件,手动打开确认是否是正常的10日天气预报页面:with open("test.html", "w", encoding="utf-8") as f: f.write(page.text) - 更新节点选择器
打开你要爬的目标页面,按F12调出开发者工具,用元素选择器直接点选你要提取的标题、表格等节点,复制当前页面真实的类名/选择器,替换你代码里旧的类名。 - 增加空值判断,避免链式调用报错
不要直接连续调用find()方法,先判断前一步返回的节点是否存在再操作:
后续的表格、日期、温度等字段提取都要加类似的空判断,避免某一个字段不存在直接导致程序崩溃。# 示例,类名替换为你自己查到的当前页面真实类名 title_div = soup.find("div", {"class": "你查到的标题外层div的类名"}) if title_div: title_h1 = title_div.find("h1") all = title_h1.text if title_h1 else "无标题" else: all = "无标题" - 可选:更换容错性更高的解析器
先安装lxml:pip install lxml,再修改BeautifulSoup初始化代码:soup = BeautifulSoup(page.content, "lxml")
额外提示
如果更新了选择器还是提取不到数据,大概率是当前页面的天气数据是JavaScript动态渲染的,静态请求只能拿到空的框架HTML,拿不到实际数据。这种情况可以改用Selenium、Playwright等模拟浏览器的工具加载页面后再提取,或者直接抓网站的天气数据接口请求,比解析HTML更稳定。
内容的提问来源于stack exchange,提问作者GCIreland
相关产品推荐
相关产品推荐

