scrapy默认拿不到动态加载的数据,因为其downloader仅下载初始html且不执行javascript,目标数据通常藏在fetch()或xmlhttprequest返回的json中,原始响应仅有空容器;应优先逆向xhr/fetch接口,而非启动浏览器渲染。

为什么Scrapy默认拿不到动态加载的数据
因为Scrapy的Downloader只下载初始HTML,不执行JavaScript。目标数据往往藏在fetch()或XMLHttpRequest调用返回的JSON里,原始响应中只有空容器(如<div id="list"></div>)或骨架屏。你用response.css('.item')查不到内容,不是XPath写错,是DOM根本没被JS填充过。
优先逆向XHR/Fetch接口,而不是启动浏览器
打开Chrome开发者工具 → Network → XHR/Fetch,刷新页面并滚动/点击触发加载,找到返回JSON的请求。重点确认:
-
Request URL是否含分页参数(如page=2、offset=20) -
Request Headers里是否有必需字段:User-Agent、Referer、带有效期的Cookie或X-Requested-With -
Form Data或Query String Parameters里是否存在加密字段(如sign、token)——若存在,需额外逆向,别硬上Selenium
Scrapy中直接发请求:yield scrapy.Request(url=api_url, headers=headers, callback=self.parse_api),然后用json.loads(response.text)解析,比渲染整页快5–10倍。
必须用浏览器渲染时,别在Spider里初始化driver
在spider.py的__init__里创建webdriver.Chrome()会导致每个请求都启新实例,内存暴涨且无法复用。正确做法是:
- 在自定义
DownloaderMiddleware中管理driver生命周期 - 用
process_request拦截目标请求,调用driver.get(request.url) - 用
WebDriverWait等真实元素,而非time.sleep()(易超时或过早) - 务必在
spider_closed信号里调用driver.quit(),否则进程残留
注意:Python 3.12下chromedriver需≥126版本,旧版会报SessionNotCreatedException。
Scrapy + Playwright比Selenium更稳,但要改配置
Playwright对现代JS框架(React/Vue)兼容性更好,自动等待网络空闲,且支持无头模式真后台运行。接入步骤:
- 安装:
pip install scrapy-playwright - 在
settings.py中启用:DOWNLOAD_HANDLERS = {"https": "scrapy_playwright.handler.ScrapyPlaywrightDownloadHandler"} - 给Request加meta:
request.meta["playwright"] = True,再加request.meta["playwright_page_methods"]控制滚动或点击
真正容易被忽略的是:Playwright默认超时是30秒,而某些懒加载页面需要更久;得显式设request.meta["playwright_timeout"] = 60,否则中途断掉还查不出原因。
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!











