使用requests_html和CSS选择器抓取应用名称返回空列表的问题
问题:使用requests_html和CSS选择器抓取网站应用名称返回空列表
尝试抓取指定网站底部的应用名称,但使用requests_html的CSS选择器始终返回空列表,相关代码如下:
import requests_html from requests_html import HTMLSession s = HTMLSession() headers = { "User-Agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36" } url = 'https://www.workato.com/integrations/salesforce' r = s.get(url, headers=headers) r.html.render(sleep=4) apps = r.html.find('#__layout > div > div > div > div > div > main > article.apps-page__section.apps-page__section_search > div > div > div.apps-page__integrations > div > ul') print(apps)
尝试遍历列表或调用.text属性,输出始终为[]。
原因分析
- 你使用的CSS选择器过于冗长,完全依赖页面的深层DOM层级结构,这类结构极易因网站前端框架的动态渲染、组件更新或异步加载逻辑而失效
- 即使调用了
r.html.render(),4秒的等待时间可能不足以让目标内容通过异步请求加载完成,render()默认仅处理初始页面渲染,不会主动等待所有AJAX请求结束 - 网站的反爬机制或请求头不完整,可能导致渲染后的页面未加载出目标内容
解决方法
1. 简化CSS选择器
放弃依赖深层DOM路径,改用目标元素的类名定位,更稳定可靠:
# 定位应用列表容器内的ul apps = r.html.find('div.apps-page__integrations ul') # 直接定位所有应用列表项 app_items = r.html.find('div.apps-page__integrations ul li')
如果要提取应用名称,可进一步获取列表项内的文本:
for item in app_items: print(item.text.strip())
2. 优化页面渲染参数
延长等待时间,或启用keep_page=True保持页面连接,确保异步内容加载完成:
r.html.render(sleep=6, keep_page=True)
3. 验证渲染后的页面内容
将渲染后的页面源码保存到本地,检查目标内容是否存在,以此排查是选择器问题还是渲染问题:
with open('rendered_page.html', 'w', encoding='utf-8') as f: f.write(r.html.html)
打开保存的HTML文件,搜索apps-page__integrations确认目标列表是否存在。
4. 完善请求头
添加更多浏览器常用请求头,模拟更真实的请求:
headers = { "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36", "Accept-Language": "zh-CN,zh;q=0.9", "Referer": "https://www.workato.com/" }
内容的提问来源于stack exchange,提问作者Ahmad Abdelbaset
相关产品推荐
相关产品推荐

