Разбор HTML-данных с помощью lxml - PullRequest
2 голосов
/ 26 декабря 2011

Я новичок в кодировании, и мой друг сказал мне использовать BeautifulSoup вместо htmlparser. После некоторых проблем я получил совет использовать lxml вместо BeaytifulSoup, потому что он в 10 раз лучше.

Я надеюсь, что кто-нибудь подскажет, как почистить текст, который я ищу.

Я хочу найти таблицу со следующими строками и данными:

<tr>
    <td><a href="website1.com">website1</a></td>
    <td>info1</td>
    <td>info2</td>              
    <td><a href="spam1.com">spam1</a></td>
</tr>
<tr>
    <td><a href="website2.com">website2</a></td>
    <td>info1</td>
    <td>info2</td>              
    <td><a href="spam2.com">spam2</a></td>
</tr>

Как мне очистить сайт с информацией 1 и 2, без спама, с lxml и получить следующие результаты?

[['url' 'info1', 'info2'], ['url', 'info1', 'info2']]

Ответы [ 3 ]

4 голосов
/ 26 декабря 2011
import lxml.html as lh

tree = lh.fromstring(your_html)

result = []
for row in tree.xpath("tr"):
    url, info1, info2 = row.xpath("td")[:3]
    result.append([url.xpath("a")[0].attrib['href'],
                   info1.text_content(),
                   info2.text_content()])

Результат:

[['website1.com', 'info1', 'info2'], ['website2.com', 'info1', 'info2']]
4 голосов
/ 26 декабря 2011

Я использую xpath : td/a[not(contains(.,"spam"))]/@href | td[not(a)]/text()

$ python3
>>> import lxml.html
>>> doc = lxml.html.parse('data.xml')
>>> [[j for j in i.xpath('td/a[not(contains(.,"spam"))]/@href | td[not(a)]/text()')] for i in doc.xpath('//tr')]
[['website1.com', 'info1', 'info2'], ['website2.com', 'info1', 'info2']]
1 голос
/ 26 декабря 2011
import lxml.html as LH

doc = LH.fromstring(content)
print([tr.xpath('td[1]/a/@href | td[position()=2 or position()=3]/text()')
       for tr in doc.xpath('//tr')])

Длинный XPath имеет следующее значение:

td[1]                                   find the first <td>  
  /a                                    find the <a>
    /@href                              return its href attribute value
|                                       or
td[position()=2 or position()=3]        find the second or third <td>
  /text()                               return its text value
...