Scrapy结合Docker抓取Tooltip动态内容,求正确选择器语法
问题解决思路
一、先修正选择器写法
你的目标元素是带spc spc-nowrap类的元素,嵌套在id="tooltipdiv"的隐藏div里,先给你正确的选择器:
CSS选择器写法
如果目标元素是span标签,精准定位的CSS选择器可以这么写:
#tooltipdiv .spc.spc-nowrap::text
在Scrapy里调用的话:
# 获取单个文本 response.css("#tooltipdiv .spc.spc-nowrap::text").get() # 获取所有匹配的文本列表 response.css("#tooltipdiv .spc.spc-nowrap::text").getall()
XPath选择器写法
两种匹配逻辑,按需选:
- 严格匹配完整class值:
//div[@id='tooltipdiv']//*[@class='spc spc-nowrap']/text()
- 匹配包含目标class的元素(避免class顺序或额外类影响):
//div[@id='tooltipdiv']//*[contains(@class, 'spc') and contains(@class, 'spc-nowrap')]/text()
Scrapy调用示例:
response.xpath("//div[@id='tooltipdiv']//*[@class='spc spc-nowrap']/text()").get()
二、为什么返回空列表?核心问题:动态加载
Scrapy默认抓取的是服务器返回的静态HTML,而你说的tooltipdiv是隐藏且动态生成的——大概率是页面加载后由JavaScript触发(比如鼠标hover)才生成/填充内容,静态爬取根本拿不到这部分数据。
解决动态加载的两种方案
直接抓接口(优先选)
打开浏览器F12的「网络」面板,触发tooltip显示(比如把鼠标放到触发元素上),找到加载tooltip内容的AJAX接口,直接用Scrapy请求这个接口拿数据,这是最效率的方式,不用渲染页面。用浏览器渲染工具(Selenium/Playwright)
找不到接口的话,就用工具模拟浏览器加载页面,执行触发tooltip的操作后再提取内容。结合Docker的话,需要在容器里装好对应浏览器和驱动:
- 比如用Playwright的示例代码:
from scrapy import Spider from playwright.sync_api import sync_playwright class DynamicSpider(Spider): name = 'tooltip_spider' start_urls = ['你的目标页面URL'] def parse(self, response): with sync_playwright() as p: # 无头模式启动浏览器 browser = p.chromium.launch(headless=True, args=["--no-sandbox"]) page = browser.new_page() page.goto(response.url) # 模拟hover触发tooltip显示,替换成实际的触发元素选择器 trigger_elem = page.locator('触发tooltip的元素选择器') trigger_elem.hover() # 提取目标文本 target_text = page.locator('#tooltipdiv .spc.spc-nowrap').text_content() yield {'target_text': target_text} browser.close()
Docker容器配置注意事项
- 构建镜像时要安装Python、Scrapy、Playwright/selenium,还要安装对应浏览器(比如
playwright install chromium)。 - 启动容器时要加
--no-sandbox参数适配无头模式,命令示例:
docker run -v $(pwd):/app your-scrapy-image scrapy crawl tooltip_spider
内容的提问来源于stack exchange,提问作者Michael
相关产品推荐
相关产品推荐

