requests_html的find方法返回空数组(CSS选择器无问题)
问题原因
OpenSea是基于React构建的JS动态渲染单页应用,requests_html的get()方法默认仅抓取服务端返回的初始静态HTML源码,不会执行页面内嵌的JS逻辑加载动态生成的内容。
两段代码的结果差异和CSS选择器语法无关:
- 第一段匹配的
#main > div > div.sc-1xf18x6-0.enKNee > div > div:nth-child(3)是初始HTML中就存在的页面骨架容器节点,因此可以正常匹配返回对应元素 - 第二段追加
> div要查找的子级div,全部是页面JS运行完成后才动态插入到容器内的列表内容,初始静态源码中该容器节点内部没有对应div子节点,因此匹配结果为空数组。
解决方法
- 调用
requests_html内置的渲染能力,拉取页面后先运行JS等待动态内容加载完成,再执行元素匹配。该功能依赖Chromium环境,首次运行会自动下载对应依赖。
调整后的参考代码如下:from requests_html import HTMLSession url = 'https://opensea.io/rankings' session = HTMLSession() r = session.get(url) # 执行页面渲染,wait参数可根据网络情况调整,等待动态内容加载完成 r.html.render(timeout=20, wait=3) collections = r.html.find('#main > div > div.sc-1xf18x6-0.enKNee > div > div:nth-child(3) > div') print(collections) - OpenSea页面中类似
sc-1xf18x6-0.enKNee的类名是前端构建时自动生成的随机类名,会随页面版本发布频繁变动,长期使用的爬虫不要依赖这类动态类名编写选择器,优先选择稳定的角色属性、功能区块固定标识定位元素,避免代码随页面更新频繁失效。 - 如果执行渲染后仍然匹配不到结果,先打印
r.html.html查看实际拿到的页面源码,确认是否被反爬策略拦截返回了验证页面,或是动态渲染后的DOM层级和浏览器开发者工具中看到的结构存在差异。
内容的提问来源于stack exchange,提问作者joonoo noo
相关产品推荐
相关产品推荐

