2017-07-29 223 views
0

部分,我刮看起來像這樣的HTML:Scrapy - 選擇XPath使用正則表達式

<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() 

我這樣做是爲了保持一致性,因爲在出​​生地,我只是想提取文本,不包括所有的html屬性。所以我會得到德國的烏爾姆。

問題是,當我使用contains(text(),「Name」)時,Birth Name的條目也匹配。構建我的選擇器時如何避免這種情況?

通過正則表達式,我可以指定類似於text()的內容匹配^ Name。*,因爲文本Name可以後面跟一個冒號和或空格。

有沒有辦法使用正則表達式來解決這個問題?

回答

3

如果你想使用正則表達式,你可以試試這個:

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

但是,你正在使用的開始,與

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

謝謝你顯示兩個選項!我沒有意識到啓動功能,這正是我所需要的。 – wayway

1

嘗試提取所有元素裏的文本,然後解析文本列表,像這樣:

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']