Scrapy - 使用正则表达式

时间:2017-07-29 01:29:23

标签: python python-2.7 xpath web-scraping scrapy

我正在抓的部分HTML看起来像这样:

<h2> <span class="headline" id="Profile">Profile</span></h2>
<ul><li> <b>Name</b> Albert Einstein
</li><li> <b>Birth Name:</b> Alberto Ein
</li><li> <b>Birthdate:</b> December 24, 1986
</li><li> <b>Birthplace:</b> <a href="/Ulm" title="Dest">Ulm</a>, Germany
</li><li> <b>Height:</b> 178cm
</li><li> <b>Blood Type:</b> A
</li></ul>

我想提取每个组件 - 所以姓名,出生姓名,生日等等。

提取我的名字:

a_name = response.xpath('//ul/li/b[contains(text(),"Name")]/../descendant::text()').extract()

然后我检查a_name不是空列表,我打电话给:

"".join(a_name[2:]).strip()

我这样做是为了保持一致性,因为在Birthplace中,我只想提取文本,不包括所有的html属性。所以我会得到德国的乌尔姆。

问题在于,当我使用contains(text(),&#34; Name&#34;)时,Birth Name的条目也匹配。在构建选择器时如何避免这种情况?

使用正则表达式,我可以指定类似text()匹配^ Name。*的内容,因为文本名称后面可能跟有冒号或空格。

有没有办法使用正则表达式来解决这个问题?

2 个答案:

答案 0 :(得分:3)

如果你想使用正则表达式,你可以试试这个:

response.xpath('//ul/li/b[text()[re:test(., '^Name.*')]]/../descendant::text()') 

但你最好使用start-with

response.xpath('//ul/li/b[starts-with(text(),"Name")]/../descendant::text()')

答案 1 :(得分:1)

尝试为所有元素li提取文本,然后解析文本列表,如下所示:

from scrapy.selector import Selector
source = '''
<h2> <span class="headline" id="Profile">Profile</span></h2>
<ul><li> <b>Name</b> Albert Einstein
</li><li> <b>Birth Name:</b> Alberto Ein
</li><li> <b>Birthdate:</b> December 24, 1986
</li><li> <b>Birthplace:</b> <a href="/Ulm" title="Dest">Ulm</a>, Germany
</li><li> <b>Height:</b> 178cm
</li><li> <b>Blood Type:</b> A
</li></ul>
'''

a_name = Selector(text=source).xpath('//ul/li//text()').extract()
all_li = ''.join(a_name).strip().split("\n")
print(all_li)

all_li会给你:

[u'Name Albert Einstein', u' Birth Name: Alberto Ein', u' Birthdate: December 24, 1986', u' Birthplace: Ulm, Germany', u' Height: 178cm', u' Blood Type: A']