使用lxml解析HTML数据

3

我是一个编程初学者,我的朋友告诉我要使用BeautifulSoup而不是htmlparser。但是在遇到一些问题后,我得到了一个提示,应该使用lxml,因为它比BeautifulSoup好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>

如何使用 lxml 无需垃圾信息地抓取带有信息1和信息2的网站,并获得以下结果?

[['url' 'info1', 'info2'], ['url', 'info1', 'info2']]
3个回答

4
我使用xpathtd / a [not(contains(。,“垃圾邮件”))] / @ 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']]

所有的表格行在表格内都是相同的。我正在使用Python 2.7.2+。在表格行中,我只想要前三个作为结果。所以[['url(website1)', 'info1', 'info2'], ['url(website2)','info1', 'info2']]。谢谢您的回复。 - Retrace
我认为可以安全地假设实际内容不会包含“垃圾邮件”这个词。虽然只有@Trees能够真正告诉我们数据的哪些方面是一致的。 - Acorn
@Acorn 更改为 contains(.,"spam")spam 可以替换为类似于 ad.website.com 的模式。 - kev

4
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', '信息1', '信息2'], ['website2.com', '信息1', '信息2']]

1
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

你用几行代码让我开心了一整天。感谢你的解释。实际上所有的答案都很好。我正在学习使用Firebug获取xpath,但是这种方法更容易找到第一行表格并处理其中的数据。再次感谢大家,圣诞快乐 :) - Retrace

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接