如何使用 Scrapy 爬取动态生成的 JavaScript 图表数据?

2023-04-17 00:00:00 生成 如何使用 图表

要使用 Scrapy 爬取动态生成的 JavaScript 图表数据,需要先找到从哪个 URL 获取到了该数据。

一般情况下,这些数据都是以 JSON 格式嵌入在 HTML 页面中,并使用 JavaScript 在浏览器中渲染成图表。在 Scrapy 中,我们可以使用 Splash 或 Selenium 等工具模拟浏览器操作,从而获取到页面内容中的 JavaScript 图表数据。

下面是一个使用 Splash 的 Scrapy 爬虫例子,以对页面 https://pidancode.com/ 生成的“访问量统计”图表数据进行爬取:

首先需要在 Scrapy 的配置文件中启用 SplashMiddleware:

DOWNLOADER_MIDDLEWARES = {
    'scrapy_splash.SplashCookiesMiddleware': 723,
    'scrapy_splash.SplashMiddleware': 725,
    'scrapy.downloadermiddlewares.httpcompression.HttpCompressionMiddleware': 810,
}

然后在 Scrapy 的 Spider 中发送 Splash 请求,获取数据:

import scrapy
from scrapy_splash import SplashRequest
import json

class MySpider(scrapy.Spider):
    name = 'myspider'
    start_urls = ['https://pidancode.com/']

    def start_requests(self):
        for url in self.start_urls:
            yield SplashRequest(url, self.parse,
                endpoint='render.json',
                args={'wait': 0.5},
            )

    def parse(self, response):
        chart_data = response.xpath('//script[contains(text(), "stat_data")]')
        if chart_data:
            # 从页面中获取 JavaScript 图表数据
            chart_data = chart_data.re(r'stat_data":([^}]+)}')
            chart_data = chart_data[0].replace('\\/', '/')
            chart_data = json.loads(chart_data)

            # 处理数据,按需处理
            ...

在上面的代码中,我们首先使用 SplashRequest 发送请求,等待 0.5 秒后让页面完成渲染。然后在 parse 方法中,使用 XPath 语法提取出 JavaScript 中的图表数据,再使用正则表达式或 json.loads 将数据转换成 python 对象,最后按需处理数据。

需要注意的是,如果需要执行 JavaScript 代码来获取动态渲染的数据,需要通过 args 参数将需要执行的代码传入 Splash,例如:

args={'wait': 0.5, 'lua_source': "document.getElementById('myChart').getAttribute('data-chart-data')"}

这样,Splash 就会使用传入的代码获取到动态生成的数据。

相关文章