使用 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
,所以更好 .
我是 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
,所以更好