python - Scrapy:提取字典存储为脚本标签中的文本
问题描述
主题:提取存储在脚本标签中的字典。
你好,
我正在尝试从标签中抓取这些数据。
目标是能够提取数据字典并获取每个键值对的值。
Example:
print(digitalData['page']['pageInfo']['language'])
>>> en
我已经编写了下面的代码,一切正常,直到第 3 步我尝试使用 ast 模块将字符串转换为字典。
我收到以下错误消息:
ValueError: malformed node or string: <_ast.Name object at 0x00000238C9100B48>
剪贴代码
import scrapy
import re
import pprint
import ast
class OptumSpider(scrapy.Spider):
name = 'optum'
allowed_domains = ['optum.com']
start_urls = ['http://optum.com/']
def parse(self, response):
#Step 1: remove all spaces, new lines and tabs
#string = (re.sub('\s+','',response.xpath('//script/text()')[2].extract()))
string = (re.sub('[\s+;]','',response.xpath('//script/text()')[2].extract()))
print(string)
# Step 2: convert string to dictionary. Creates a key as "digitalData"
key, value = string.split("=")
my_dict = {key: value}
print(my_dict)
# Step 3: extract dictionary
print(my_dict['digitalData']) # result is a dictionary stored as a string.
print(type(my_dict['digitalData'])) # shows data type as string.
#ast.literal_eval(my_dict['digitalData']) # convert string to dictionary.
我收到以下错误消息:
ValueError: malformed node or string: <_ast.Name object at 0x00000238C9100B48>
请就如何解决提出意见。如果有其他方法可以接近或解决,请提出建议。
解决方案
您的问题是在提取的 Javascript 字典中:您有对象。
{
page: {
pageInfo: {
destinationURL: window.location.href,
error: '',
language: 'en',
country: 'US',
pageName: 'tangelo2',
articlepubdate: '',
articleenddate: '',
pageTitle: 'HealthServicesInnovationCompany',
pageOwner: '',
pageTemplate: '',
pageCampaign: '',
tags: '',
pageLastPublishDate: '2020-01-08T12:15:04.032-06:00',
pageLastPublishedBy: 'admin',
pageLastModifiedDate: '2020-01-08T10:24:36.466-06:00',
pageLastModifiedBy: 'katrina'
},
recEngine: {
title: 'Home',
image: '',
description: ''
},
category: {
siteName: window.location.hostname.replace("www.", ""),
version: '3.0',
contentType: '',
contentTopic: '',
contentSegment: '',
contentInitiative: '',
contentProduct: '',
contentProductLine: '',
primaryCategory: 'tangelo2'
}
},
event: {}
}
注意page.pageInfo.destinationURL
和page.category.siteName
值。
发生的情况是,ast.literal_eval
您可能尝试将此 Javascript 字典转换为 Python 的任何其他方法都会导致错误。在通过、或任何其他工具处理之前,您需要找到一种方法将其window...
从中删除。my_dict['digitalData']
ast
demjson
一种可能的解决方案是这样的,利用demjson
as 反对ast
.
import scrapy
import pprint
import demjson
import re
class OptumSpider(scrapy.Spider):
name = 'optum'
allowed_domains = ['optum.com']
start_urls = ['http://optum.com/']
def parse(self, response):
#Step 1: remove all spaces, new lines and tabs
string = (re.sub('[\s+;]','',response.xpath('//script/text()')[2].extract()))
# Step 2: convert string to dictionary. Creates a key as "digitalData"
js_dict = string.split("=")[1]
js_dict = re.sub(r"\bwindow(.*?),\b", '"",', js_dict)
# Step 3: extract dictionary
my_dict = demjson.decode(js_dict)
pprint.pprint(my_dict)
print(type(my_dict))
正在运行
scrapy runspider test.py -s LOG_ENABLED=False
它输出:
{'event': {},
'page': {'category': {'contentInitiative': '',
'contentProduct': '',
'contentProductLine': '',
'contentSegment': '',
'contentTopic': '',
'contentType': '',
'primaryCategory': 'tangelo2',
'siteName': '',
'version': '3.0'},
'pageInfo': {'articleenddate': '',
'articlepubdate': '',
'country': 'US',
'destinationURL': '',
'error': '',
'language': 'en',
'pageCampaign': '',
'pageLastModifiedBy': 'katrina',
'pageLastModifiedDate': '2020-01-08T10:24:36.466-06:00',
'pageLastPublishDate': '2020-01-08T12:15:04.032-06:00',
'pageLastPublishedBy': 'admin',
'pageName': 'tangelo2',
'pageOwner': '',
'pageTemplate': '',
'pageTitle': 'HealthServicesInnovationCompany',
'tags': ''},
'recEngine': {'description': '', 'image': '', 'title': 'Home'}}}
<class 'dict'>
推荐阅读
- r - 如何使用 for 循环获取每个列的异常值?
- java - 通过 Java 中的接口调用时变量赋值被延迟
- c# - 将 StringSegment 附加到 StringBuilder
- python - 如何将 pandas 数据框转换为具有列名的 numpy 数组
- django - 以条带形式访问 webbook 中的优惠券信息
- json - 通过 Cloud Formation 控制数据库安全组端口访问
- json - Rocket 无法解析 JSON 正文
- python - Pytss:将参数传递给 fapi_Sign() 方法 - 无效的参数类型(类型为 uint8_t const * 的 Fapi_Sign 参数 4)
- c++ - 在两个字符串 C++ 中找到最长的子字符串
- java - 尝试在Java中将变量从方法调用到main