You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用Scrapy框架等待页面完全加载以爬取目标数据?

解决办法

你碰到的问题核心是:页面里的目标数据是JavaScript动态渲染出来的,Scrapy默认抓取的是服务器返回的初始HTML,而你在浏览器审查元素看到的是渲染后的DOM结构,所以初始HTML里根本没有那个XPath对应的元素。

当然可以通过等待页面加载来提取数据,但得配合能处理JS渲染的工具,给你两种实用方案:

方案1:用Playwright配合Scrapy模拟浏览器加载

Playwright能模拟浏览器完整加载页面,等JS执行完毕后再抓取DOM,步骤如下:

  1. 先安装依赖:pip install scrapy-playwright
  2. 在Scrapy的settings.py中添加配置:
    DOWNLOAD_HANDLERS = {
        "http": "scrapy_playwright.handler.ScrapyPlaywrightDownloadHandler",
        "https": "scrapy_playwright.handler.ScrapyPlaywrightDownloadHandler",
    }
    SPIDER_MIDDLEWARES = {
        "scrapy_playwright.middleware.PlaywrightMiddleware": 543,
    }
    
  3. 在爬虫代码中设置等待元素加载:
    def start_requests(self):
        yield scrapy.Request(
            url="https://openweathermap.org/city/625665",
            meta={"playwright": True, "playwright_include_page": True},
            callback=self.parse,
        )
    
    async def parse(self, response):
        page = response.meta["playwright_page"]
        # 等待目标元素加载完成
        await page.wait_for_selector('//*[@id="weather-widget"]/div[2]/div[1]/div[1]/div[1]/h2')
        # 获取渲染后的页面内容
        rendered_html = await page.content()
        selector = scrapy.Selector(text=rendered_html)
        target_data = selector.xpath('//*[@id="weather-widget"]/div[2]/div[1]/div[1]/div[1]/h2/text()').get()
        print(target_data)
        await page.close()
    

方案2:直接爬取后台API(更高效)

打开浏览器开发者工具的「网络」标签,刷新页面后筛选XHR类型的请求,你会发现天气数据其实是通过API接口返回的JSON。直接请求这个API比模拟浏览器加载快得多,还能避免JS渲染的麻烦——找到类似/data/2.5/weather的接口,带上城市ID参数就能拿到结构化数据。

内容的提问来源于stack exchange,提问作者Zakhar Malinouski

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.02 16:50:20