为何requests-html无法渲染全部HTML内容?
速卖通页面渲染不全问题(基于requests-html)
尝试爬取速卖通搜索页面数据时,即便调整render的sleep参数,脚本也无法稳定加载全部HTML内容,多次运行结果不一致:有时能获取到目标元素,有时完全加载失败。
原代码
from requests_html import HTMLSession, AsyncHTMLSession url = 'https://www.aliexpress.com/w/wholesale-test.html?catId=0&initiative_id=SB_20230516115154&SearchText=test&spm=a2g0o.home.1000002.0' def create_session(url): session = HTMLSession() request = session.get(url) print("Before ",len(request.html.html),"\n\n") request.html.render(sleep=5,timeout=20) #Because it is dynamic website, will wait until to load the page prod = request.html.find('#root > div > div > div.right--container--1WU9aL4.right--hasPadding--52H__oG > div > div.content--container--2dDeH1y > div.list--gallery--34TropR > a:nth-child(1) > div.manhattan--content--1KpBbUi') print("After ",len(request.html.html),"\n\n") print("output:",prod) session.close() create_session(url)
不同运行结果
- 首次运行输出
Before 55448 After 542927 output: [<Element 'div' class=('manhattan--content--1KpBbUi',)>]
- 未修改代码二次运行输出
Before 55448 After 251734 output: []
- 修改sleep为100后的输出
Before 55448 After 242881 output: []
问题原因及解决办法
- 反爬拦截:速卖通会检测请求特征(如无真实UA、频繁请求),多次请求后触发反爬,导致页面渲染不完整。解决:添加真实浏览器的请求头,模拟正常用户行为。
- 固定sleep不可靠:页面采用异步加载,固定等待时间无法保证元素加载完成。解决:改用
wait参数等待目标容器出现,确保渲染完成后再查找元素。 - 选择器不稳定:依赖DOM层级的选择器(如
a:nth-child(1))容易因页面结构变化失效。解决:改用更稳定的class选择器。 - 会话状态缺失:每次新建会话可能丢失必要的Cookie或会话信息,被识别为机器人。解决:复用会话或添加登录后的Cookie(若需)。
修改后的示例代码
from requests_html import HTMLSession url = 'https://www.aliexpress.com/w/wholesale-test.html?catId=0&initiative_id=SB_20230516115154&SearchText=test&spm=a2g0o.home.1000002.0' def create_session(url): session = HTMLSession() # 添加真实浏览器请求头 headers = { 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36' } request = session.get(url, headers=headers) print("Before ", len(request.html.html), "\n\n") # 等待目标列表容器加载完成后再渲染 request.html.render( sleep=3, timeout=30, wait='#root > div > div > div.right--container--1WU9aL4.right--hasPadding--52H__oG > div > div.content--container--2dDeH1y > div.list--gallery--34TropR' ) # 使用更稳定的class选择器 prod = request.html.find('div.manhattan--content--1KpBbUi') print("After ", len(request.html.html), "\n\n") print("output:", prod) session.close() create_session(url)
内容的提问来源于stack exchange,提问作者Ahmad Abdelbaset
相关产品推荐
相关产品推荐

