Beautifulsoup 4 .find_all()爬取谷歌学术时突然失效返回空值
BeautifulSoup查找谷歌学术
gs_ri元素返回空的排查方案 - 先查最核心的问题:你拿到的响应根本不是正常的搜索结果页
不要觉得状态码200、soup能正常生成就代表内容正确。谷歌学术的反爬拦截页、人机验证页、访问频率超限提示页都是标准HTML,BeautifulSoup完全可以正常解析生成对象,但这些页面里根本不存在class为gs_ri的div,find_all返回空是必然结果。你本地测试用的是之前存好的正常结果页,自然不会复现这个问题。
验证方法很简单:把当前请求拿到的site.text写入本地htm文件,直接用浏览器打开看,90%的概率你会看到验证码或者“您的网络发出的请求异常”之类的提示。 - 补全合法请求头,绕过基础反爬识别
谷歌的反爬规则是动态更新的,之前能用的裸请求(不带任何头)现在大概率会被识别为爬虫。最基础的修复就是给请求加上正常浏览器的User-Agent,参考代码:
import requests from bs4 import BeautifulSoup as bs 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" } site = requests.get(url, headers=headers, timeout=10) # 手动指定编码,避免因编码识别错误导致class属性乱码、匹配失败 site.encoding = site.apparent_encoding soup = bs(site.text, "html.parser") ri = soup.find_all("div", class_="gs_ri")
- 校验页面结构是否有调整
直接在site.text里搜索gs_ri字符串,如果完全搜不到,排除拦截问题的话,说明你命中了谷歌学术的灰度测试页面,文献列表块的class名做了调整,直接从返回的页面源码里重新定位对应元素的属性即可。 - 低概率问题:解析器兼容问题
如果线上环境的BeautifulSoup版本、Python版本和你本地测试环境不一致,极少数情况会出现html.parser解析异常,可以换用lxml解析器测试(需要先执行pip install lxml安装),初始化soup时改为soup=bs(site.text, 'lxml')即可。
注意:谷歌学术反爬阈值非常低,高频无间隔请求、机房IP请求很容易被临时封禁,爬取时建议添加3-5秒的随机请求间隔,避免IP被长期限制。
内容的提问来源于stack exchange,提问作者Bernát Kun
相关产品推荐
相关产品推荐

