【问题标题】:Fetch page with Scrapy, execute JS and extract variable使用 Scrapy 获取页面,执行 JS 并提取变量
【发布时间】:2019-10-01 17:27:17
【问题描述】:

我有一个项目使用 python 屏幕抓取框架scrapy。我创建了一个蜘蛛,它加载所有<script> 标签并处理第二个标签。这是因为在我收集的测试数据中,我需要的数据位于第二个<script> 标记中。

但现在我遇到了一个问题,而某些页面包含我想要的其他脚本标签(#3 或 #4)中的数据。进一步的障碍是第二个javascript标签的第二行大部分都有我想要的JSON。但根据页面的不同,这也可能是第 3 行或第 4 行。

考虑这个简单的 HTML 文件:

<html>
    <head>
        <title> Test </title>
    </head>

    <body>
        <p>
            This is a text
        </p>

        <script type="text/javascript">
            var myJSON = {
                a: "a",
                b: 42
            }
        </script>
    </body>
</html>

如果我在浏览器 (firefox) 中打开此页面并转到开发人员工具和 console.log(myJSON.b),我可以访问 myJSON.b 并获得 42 所以我的问题是:如何从 scrapy-fetched-page 中提取 JavaScript 变量或 JSON?

【问题讨论】:

  • 您将使用Selenium 来控制可以运行JavaScript 的真实Web 浏览器。或过时的PhantomJS。或 Splash 甚至还有 Scrapy 插件:scrapy-splash
  • @furas 我完全不同意。 Selenium 首先是一个 webtester,而不是一个 webcrawler。所以加载页面和一些无用的东西需要更多的时间,因为有很多方法可以提取 json 模式而没有任何麻烦。我的意思是我也排除了scrapy-splash。

标签: python web-scraping scrapy


【解决方案1】:

我之前遇到过类似的问题,我通过使用类似(基于您的示例 HTML 文件)提取脚本标记中的文本来解决它:

response.xpath('//script/text()')

之后,我使用正则表达式以 JSON 格式提取所需的数据。因此,使用上面的选择器和您的示例 HTML,接近于:

pattern = r'i-suck-at-regular-expressions'
json_data = response.xpath('//script/text()').re_first(pattern)

接下来,您应该可以使用 json 库将数据加载为 python 字典,如下所示:

json.loads(json_data)

它应该返回类似于:

{"a": "a", "b": 42}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-10-12
    • 2015-04-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-06-02
    相关资源
    最近更新 更多