2016-11-06 25 views
0

lxml返回兩個項目,而beautifulsoup只返回一個元素。那是因爲<br/>不應該在那裏,美麗的女孩更容忍不良的HTML?lxml分隔元素而beautifulsoup不

有沒有更好的方法來使用lxml提取位置? <br/>並不總是在那裏。

from lxml import html 
from bs4 import BeautifulSoup as bs 

s = '''<td class="location"> 
    <p> 
    TRACY,<br/>&nbsp;CA&nbsp;95304&nbsp; 
    </p></td> 
''' 

tree = html.fromstring(s) 
r = tree.xpath('//td[@class="location"]/p/text()') 
print r 

soup = bs(s, 'lxml') 
r = soup.find_all('td', class_='location')[0].get_text() 
print r 

回答

1

有沒有更好的方法來使用lxml提取位置? <br/>並不總是在那裏。

如果通過更好你的意思是返回結果更接近它的BS對應,則XPath表達式更好地模擬你的廢話,代碼如下:

>>> print tree.xpath('string(//td[@class="location"])') 


    TRACY, CA 95304  

而且,如果你喜歡多餘的空格被刪除,使用normalize-space()代替string()

>>> print tree.xpath('normalize-space(//td[@class="location"])') 
TRACY, CA 95304  
0

element.get_text()加入單獨的字符串運行;從documentation

如果您只想要文本或標記的文本部分,則可以使用get_text()方法。它返回一個文檔中的所有文本或標籤的下面,作爲一個Unicode字符串

重點煤礦。

使用Tag.strings generator,如果你要在各個字符串:

>>> list(soup.find_all('td', class_='location')[0].strings) 
[u'\n', u'\n TRACY,', u'\xa0CA\xa095304\xa0\n '] 

如果你想LXML加入文字,那麼就加入文字:

r = ''.join(tree.xpath('//td[@class="location"]/p/text()')) 

string() XPath function可以做同樣的<td>標籤:

r = tree.xpath('string(//td[@class="location"])') 

演示:

>>> ''.join(tree.xpath('//td[@class="location"]/p/text()')) 
u'\n TRACY,\xa0CA\xa095304\xa0\n ' 
>>> tree.xpath('string(//td[@class="location"])') 
u'\n \n TRACY,\xa0CA\xa095304\xa0\n ' 

我在任的結果使用str.strip()

>>> tree.xpath('string(//td[@class="location"])').strip() 
u'TRACY,\xa0CA\xa095304' 
>>> print tree.xpath('string(//td[@class="location"])').strip() 
TRACY, CA 95304 

或使用normalize-space() XPath function

>>> tree.xpath('normalize-space(string(//td[@class="location"]))') 
u'TRACY,\xa0CA\xa095304\xa0' 

注意str.strip()去掉尾隨的非破\xa0空間,同時normalise-space()葉它。

+0

我正在尋找從LXML一個字符串,而不是進一步分離bs的結果。 「有沒有更好的方法來使用lxml提取位置?」 – foosion

+0

@福發:啊,的確,讀得太快了。 –

+0

感謝您的嘗試 – foosion