在Scrapy中,如何根据匹配正则表达式

时间:2017-04-13 16:51:23

标签: python xpath scrapy

我正试图以可靠的方式抓取APKmirror.comhttp://www.apkmirror.com/apk/shareit-technologies-co-ltd/shareit-connect-transfer/shareit-3-0-38_ww-release/shareit-3-0-38_ww-android-apk-download/下载页面。

我已经从

命令行启动了Scrapy shell
scrapy shell http://www.apkmirror.com/apk/shareit-technologies-co-ltd/shareit-connect-transfer/shareit-3-0-38_ww-release/shareit-3-0-38_ww-android-apk-download/

我目前正试图从顶部导航栏中删除开发者名称,应用名称和版本名称:

enter image description here

在这种情况下分别是“SHAREit Technologies Co.Ltd”,“SHAREit - Transfer& Share”和“3.0.38_ww”。

到目前为止,我已经为开发者名称提出了以下XPath表达式:

In [84]: response.xpath('//*[@class="site-header-contents"]//nav//a/text()').extract()[0]
Out[84]: u'SHAREit Technologies Co.Ltd'

对于应用和版本名称,我将分别用[0][1]替换[2]。问题是使用数字指数不被认为是良好的刮削实践。

相反,我想在这些链接之间使用“真正的”区别特征:它们的URL包含不同数量的斜杠(/)。我想定义一个自定义选择器,它将a/@href与正则表达式匹配,如果匹配,则返回a/text(),但我无法弄清楚如何执行此操作。 (例如,re方法(https://doc.scrapy.org/en/0.10.3/topics/selectors.html#scrapy.selector.XPathSelector.re)似乎可以替代extract(),但不能“帮助”选择过程。

如何根据应用于@href的自定义功能进行选择?

1 个答案:

答案 0 :(得分:2)

首先,如果您从面包屑中提取数据,那么在这种情况下并不一定是不好的做法。您可以保证面包屑订单始终相同 - 第一项是公司,第二项是产品,最后一项是版本 - 非常可预测!
尽管如此,您可能希望使用更可靠的xpath索引:

"//div/a[1]" 
# would get first <a> node under <div>
"//div/a[last()]"
# would get last <a> node under <div>

但是,要回答您的问题,有re:test xpath评估程序,它允许您使用常规表达式进行测试。

使用.com href:

查找具有<div>节点子节点的<a>节点
"//div[re:test(a/@href, '.+?\.com')]"  

查找包含一些文本不敏感的正则表达式匹配的<div>节点:

"//div[re:test(.//text(), 'foo.bar', 'i')]"