python - Scrapy:提取存储为脚本标签中文本的字典

标签 python scrapy abstract-syntax-tree

主题:提取存储在脚本标签中的字典。

你好,

我正在尝试从标签中抓取这些数据。

enter image description here

目标是能够提取数据字典并获取每个键值对的值。

Example:
print(digitalData['page']['pageInfo']['language'])
>>> en

我已经编写了下面的代码,一切正常,直到进入步骤 3,我尝试使用 ast 模块将字符串转换为字典。

我收到以下错误消息:

ValueError: malformed node or string: <_ast.Name object at 0x00000238C9100B48>

Scrapy 代码

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 的任何其他方法都会导致错误。在通过 ast 处理之前,您需要找到一种方法从 my_dict['digitalData'] 中删除 window...demjson,或任何其他工具。

<小时/>

一种可能的解决方案是这样的,利用 demjsonast相反。

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'>

关于python - Scrapy:提取存储为脚本标签中文本的字典,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59919426/

相关文章:

Python:如何在 Windows 上与 unicode 文件名交互? (Python 2.7)

python - 在字典中创建一个集合

exception - scrapy未处理的异常

python - Scrapy:尝试从不正确的选择器列表中提取数据

c# - 遍历具有复杂条件表达式的 ast 以生成 linq 表达式

python - 如果值相同,如何对字典中的键进行排序?

python - 如何检索模型 A 的模型列表,其中包含 B 的外键?

firefox - 在 Firefox 57 DevTools Inspector 中通过 XPath 搜索元素

json - 如何以 JSON 格式表示 clang AST?

c++ - boost::spirit 从语义 Action 访问位置迭代器