lxml разделяет элементы, а Beautifulsoup - нет
lxml возвращает два элемента, а beautifulsoup возвращает только один. Это потому что <br/>
там не должно быть и Beautifulsoup более терпим к плохим HTML?
Есть ли лучший способ извлечь местоположение с помощью lxml? <br/>
не всегда там
from lxml import html
from bs4 import BeautifulSoup as bs
s = '''<td class="location">
<p>
TRACY,<br/> CA 95304
</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
2 ответа
Есть ли лучший способ извлечь местоположение с помощью lxml?
<br/>
не всегда там
Если под лучшим вы подразумеваете возвращение результата, который ближе к его аналогу BS, то выражение XPath, которое лучше напоминает ваш код BS:
>>> print tree.xpath('string(//td[@class="location"])')
TRACY, CA 95304
Кроме того, если вы хотите удалить лишние пробелы, используйте normalize-space()
вместо string()
:
>>> print tree.xpath('normalize-space(//td[@class="location"])')
TRACY, CA 95304
element.get_text()
объединяет отдельные цепочки строк; из документации:
Если вам нужна только текстовая часть документа или тега, вы можете использовать метод get_text(). Возвращает весь текст в документе или под тегом в виде одной строки Unicode
Акцент мой.
Использовать Tag.strings
генератор, если вы хотите отдельные строки:
>>> 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 может сделать то же самое для <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:
>>> tree.xpath('normalize-space(string(//td[@class="location"]))')
u'TRACY,\xa0CA\xa095304\xa0'
Обратите внимание, что str.strip()
удаляет завершающий неразрывный \xa0
пространство, а normalise-space()
оставляет это.