Xpath意外的反斜杠问题

时间:2017-09-07 23:07:09

标签: python xpath scrapy backslash

我试图使用scrapy从HTML中提取一些json文件,我有两个问题,它们相互冲突。

其中一个是 brandName 问题,该问题出现在本网站上:http://us.asos.com/barneys-originals/barneys-faux-leather-biker-jacket/prd/7949149?clr=black&SearchQuery=barneys+faux+biker&pgesize=9&pge=0&totalstyles=9&gridsize=3&gridrow=1&gridcolumn=1

包含json文件的HTML元素的一部分如下所示:

<script type="text/javascript">
   require(['Pages/FullProduct'], function (view) {
      view('{"id":7949149,
             "name":"Barneys Faux Leather Biker Jacket",
             "brandName":"Barney\'s Originals"
      }');
   });
</script>

另一个是大小问题,该问题出现在本网站上: http://us.asos.com/asos/asos-3-pack-smart-slim-belt-in-faux-leather-save/prd/7098512?clr=multi&cid=21809

包含json文件的HTML元素的一部分如下所示:

<script type="text/javascript">
   require(['Pages/FullProduct'], function (view {
      view('{"id":7098512,
             "name":"ASOS 3 Pack Smart Slim Belt In Faux Leather SAVE",
             "brandName":"ASOS"
             "variants": [{
                "variantId": 7098598,
                "size": "S/M - W79-86cm",
                "sizeId": 3810,
                "colour": "Multi",
                "colourCode": "MU1",
                "isPrimary": true,
                "sizeOrder": 2
             }, {
                "variantId": 7098522,
                "size": "L/XXL - 36\\" - 40\\ " (91-102cm)",
                "sizeId": 7589,
                "colour": "Multi",
                "colourCode": "MU1",
                "isPrimary": true,
                "sizeOrder": 5}]');
             }]
      }');
   });
</script>

我使用了这种方法,除了包含&#34; \&#34;的文本外,效果很好:

response.xpath('//script[contains(., "Pages/FullProduct")]/text()').re_first("view\('(\{.*\})',")

我运行上面的代码,我得到了带有意外反斜杠的文本。 xpath方法将两个额外的&#34; \&#34; s添加到文本中,它应该只有一个&#34; \&#34;。它给我加载json文件时出错。

对于brandName问题:

"Barney\'s Originals"变为"Barney\\\'s Originals"

对于尺寸问题:

"L/XXL - 36\\" - 40\\ " (91-102cm)"变为"L/XXL - 36\\\\" - 40\\\\ " (91-102cm)"

然后我尝试使用replace("\\", "")方法删除额外的两个反斜杠:

response.xpath('//script[contains(., "Pages/FullProduct")]/text()').re_first("view\('(\{.*\})',").replace("\\\\", "")

执行上述操作后,brandName问题已修复,但尺寸问题变为:

"L/XXL - 36" - 40" (91-102cm)"

再次加载json文件时会出错,因为它认为前两个是一组,而后两个是一组。而且我注意到原来的html不会通过json验证器,因为它没有识别&#34; \\&#34;。

然后我针对尺寸问题尝试了replace("\\\\", "\")

response.xpath('//script[contains(., "Pages/FullProduct")]/text()').re_first("view\('(\{.*\})',").replace("\\\\", "\")

但我收到了这个错误:

SyntaxError: EOL while scanning string literal

我的问题是:如何在同一时间解决这两个相互矛盾的问题,并在任何引号之前只用一个反斜杠获取文本?

我想要的结果是:

&#34; Barney的Originals&#34; 为brandName。

&#34; L / XXL - 36 \&#34; - 40 \&#34; (91-102cm)&#34; 的大小。

1 个答案:

答案 0 :(得分:0)

在第二种情况下,以下对我来说没问题

>>> data = response.xpath('//script[contains(., "Pages/FullProduct")]/text()').re_first("view\('(\{.*\})',")
>>>
>>> data_json = json.loads(re.sub(r'[\\]+"', r'\"', data))
>>> data_json["variants"]
[{'variantId': 7098523, 'size': 'XXS/XS - W66-76cm', 'sizeId': 7588, 'colour': 'Multi', 'colourCode': 'MU1', 'isPrimary': True, 'sizeOrder': 1}, {'variantId': 7098598, 'size': 'S/M - W79-86cm', 'sizeId': 3810, 'colour': 'Multi', 'colourCode': 'MU1', 'isPrimary': True, 'sizeOrder': 2}, {'variantId': 7098522, 'size': 'L/XXL - 36" - 40" (91-102cm)', 'sizeId': 7589, 'colour': 'Multi', 'colourCode': 'MU1', 'isPrimary': True, 'sizeOrder': 5}]
>>> data_json["variants"][0]['size']
'XXS/XS - W66-76cm'
>>> data_json["variants"][1]['size']
'S/M - W79-86cm'

第一种情况下,对我来说也是如此

>>> data = response.xpath('//script[contains(., "Pages/FullProduct")]/text()').re_first("view\('(\{.*\})',")
>>> data_cleaned = re.sub(r'[\\]+"', r'\"', data)
>>> data_cleaned = re.sub(r"[\\]+'", r"'", data_cleaned)
>>> data_json = json.loads(data_cleaned)
>>> data_json['brandName']
"Barney's Originals"