首页 > 解决方案 > 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>

请就如何解决提出意见。如果有其他方法可以接近或解决,请提出建议。

标签: pythonscrapyabstract-syntax-tree

解决方案


您的问题是在提取的 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.destinationURLpage.category.siteName值。

发生的情况是,ast.literal_eval您可能尝试将此 Javascript 字典转换为 Python 的任何其他方法都会导致错误。在通过、或任何其他工具处理之前,您需要找到一种方法将其window...从中删除。my_dict['digitalData']astdemjson


一种可能的解决方案是这样的,利用demjsonas 反对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'>

推荐阅读