Scrapy - 获取JavaScript变量的值

7

使用Scrapy,我如何获得Javascript变量的值...

下面是我的代码...

<script rel="bmc-data">
      var match = 'yes';
      var country = 'uk';
      var tmData = {
        "googleExperimentVariation": "1",
        "pageTitle": "Child Care",
        "page_type": "claimed",
        "company_state": "wyostate",
        "company_city": "mycity"
                   };
</script>

我希望检查 page_type 变量的值。如果它是 "claimed",则处理该页面,否则继续执行 ....
我已经看过 这个这个 我尝试过这个...
pattern = r'page_type = "(\w+)",'
response.xpath('//script[@rel="bmc-data"]').re(pattern)

但是显然这个方法是不起作用的,因为我认为我的正则表达式有问题。

2个回答

5
我建议使用js2xml来完成此任务(免责声明:我是js2xml的作者)。
>>> import scrapy
>>> import js2xml
>>> html = '''<script rel="bmc-data">
...       var match = 'yes';
...       var country = 'uk';
...       var tmData = {
...         "googleExperimentVariation": "1",
...         "pageTitle": "Child Care",
...         "page_type": "claimed",
...         "company_state": "wyostate",
...         "company_city": "mycity"
...                    };
... </script>'''
>>> selector = scrapy.Selector(text=html)
>>> selector.xpath('//script/text()').extract_first()
u'\n      var match = \'yes\';\n      var country = \'uk\';\n      var tmData = {\n        "googleExperimentVariation": "1",\n        "pageTitle": "Child Care",\n        "page_type": "claimed",\n        "company_state": "wyostate",\n        "company_city": "mycity"\n                   };\n'
>>> jscode = selector.xpath('//script/text()').extract_first()
>>> jstree = js2xml.parse(jscode)
>>> print(js2xml.pretty_print(jstree))
<program>
  <var name="match">
    <string>yes</string>
  </var>
  <var name="country">
    <string>uk</string>
  </var>
  <var name="tmData">
    <object>
      <property name="googleExperimentVariation">
        <string>1</string>
      </property>
      <property name="pageTitle">
        <string>Child Care</string>
      </property>
      <property name="page_type">
        <string>claimed</string>
      </property>
      <property name="company_state">
        <string>wyostate</string>
      </property>
      <property name="company_city">
        <string>mycity</string>
      </property>
    </object>
  </var>
</program>

>>> jstree.xpath('//var[@name="tmData"]/object')[0]
<Element object at 0x7f0b0018f050>

>>> from pprint import pprint
>>> data = js2xml.jsonlike.make_dict(jstree.xpath('//var[@name="tmData"]/object')[0])
>>> pprint(data)
{'company_city': 'mycity',
 'company_state': 'wyostate',
 'googleExperimentVariation': '1',
 'pageTitle': 'Child Care',
 'page_type': 'claimed'}
>>> data['page_type']
'claimed'
>>> 

谢谢你的回复,保罗。对于这个简单的操作使用一个库似乎有点过度设计了... - Slyper
显然取决于使用情况。个人而言,如果可以避免编写正则表达式,我会更喜欢。这可能是品味问题。 - paul trmbrth
1
似乎缺少了一行。应该加上: jstree = js2xml.parse(jscode) - vangap

5

在这里,您的正则表达式模式有误:

# you are looking for this bit: "page_type": "claimed",
re.findall('page_type": "(.+)"', html_body)
# ["claimed"]

在您的情况下,可以使用Scrapy选择器来进行处理:

response.xpath('//script[@rel="bmc-data"]').re('page_type": "(.+)"')

如果您需要解析多个类似这样的变量,我建议采用Paul提到的答案,因为正则表达式并不总是像xml解析那样可靠。

谢谢,当我尝试您的解决方案时,出现了以下错误... AttributeError: 'function' object has no attribute 'findall' - Slyper
@PuneetSharma 看起来你有一些语法问题,可以看看我编辑的一个具体例子来解决。 - Granitosaurus

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接