Вопрос:
BeautifulSoup
обеспечивает очень ограниченную поддержку селекторов CSS. Например, единственным поддерживаемым псевдоклассом является nth-of-type
, и он может принимать только числовые значения — такие аргументы, как even
или odd
, не допускаются.
Можно ли расширить BeautifulSoup
селекторы CSS или позволить им использовать lxml.cssselect
внутри в качестве базового механизма выбора CSS?
Давайте рассмотрим пример проблемы/варианта использования. Найдите только четные строки в следующем HTML:
<table>
<tr>
<td>1</td>
<tr>
<td>2</td>
</tr>
<tr>
<td>3</td>
</tr>
<tr>
<td>4</td>
</tr>
</table>
В lxml.html
и lxml.cssselect
это легко сделать через :nth-of-type(even)
:
from lxml.html import fromstring
from lxml.cssselect import CSSSelector
tree = fromstring(data)
sel = CSSSelector('tr:nth-of-type(even)')
print [e.text_content().strip() for e in sel(tree)]
Но в BeautifulSoup
:
print(soup.select("tr:nth-of-type(even)"))
выдаст ошибку:
NotImplementedError: в настоящее время для псевдокласса nth-of-type поддерживаются только числовые значения.
Обратите внимание, что мы можем обойти это с помощью .find_all()
:
print([row.get_text(strip=True) for index, row in enumerate(soup.find_all("tr"), start=1) if index % 2 == 0])