我试图使用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; 的大小。
答案 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"