使用 scrapy 从 javascript html 标签访问 json 数据的正则表达式

regex that access json data from javascript html tag with scrapy

我是 scrapy 的新手,正在学习 atm,我正在尝试访问页面 html 上的 JSON 数据并将它们放入 python 字典中并处理数据后来所以我尝试了一些东西,都失败了,如果有人能帮助我,我将不胜感激

我在 scrapy shell:

中找到了所需标签的 response.css 结果如下所示
response.css('div.rich-snippet script').get()

'<script type="application/ld+json">{\n    some json data with newline chars \n  }\n    ]\n}</script>'

我需要 {} 之间的所有内容,但是,所以我尝试使用正则表达式,如下所示:

response.css('div.rich-snippet script').re(r'\{[^}]*\}')

这个正则表达式应该选择括号之间的所有内容,但是 JSON 中有更多这些符号,并且 JSON 数据之前的响应中还有其他内容,所以这个 returns 只是空的列表 我尝试了更多但总是相同的结果,一个空列表

.re(r'<script>\{[^}]*\}</script>')
.re(r'<script>(.|\n)*?<\/script>')
...

所以我尝试了其他方法,在蜘蛛内部我尝试直接解析对 json.loads 方法的响应并将结果保存在来自 cli 的文件中,这也不起作用,也许我正在解析标记错误或什至不可能

    import scrapy
    import json

 class SomeSpider(scrapy.Spider):
    name = 'test'
    start_urls = [
        'url'
    ]

    def parse(self, response, **kwargs):
        json_file = response.css('div.rich-snippet script').get()

        yield json.loads(json_file)

又是一个空结果

请帮我理解一下,谢谢。

您的 css 选择器应该指定您只想要标签内的部分,即应该是 ::text,因此您的代码变为:


    def parse(self, response, **kwargs):
        json_file = response.css('div.rich-snippet script::text')

        yield json.loads(json_file)

您可能还想看看: https://github.com/scrapinghub/extruct

它可能更适合解析 ld+json

您可以将响应作为字符串并使用递归正则表达式。原始 re 模块不支持递归,但较新的 regex 模块不支持递归。
也就是说,一种可能的方法是:

import regex

# code before 

some_json_string = response.css('div.rich-snippet script').get()
match = regex.search(r'\{(?:[^{}]*|(?R))+\}', some_json_string)

if match:
    relevant_json = match.group(0)
    # process it further here

表达式参见 a demo on regex101.com


编辑:

好像支持::text,所以更好.