需要Python lxml语法帮助来解析HTML

16

我是Python的新手,需要一些帮助来找到并使用lxml语法遍历HTML标签。以下是我要处理的用例:

HTML文件格式相当良好(但不完美)。页面上有多个表格,其中一个包含搜索结果集,另外还有一个头部和页脚。每个结果行都包含一个链接,用于搜索结果详细信息。

  1. 我需要找到包含搜索结果行的中间表格(这个我已经能够解决):

        self.mySearchTables = self.mySearchTree.findall(".//table")
        self.myResultRows = self.mySearchTables[1].findall(".//tr")
    
    我需要找到这个表格中包含的链接(在这里我卡住了):
  2.     for searchRow in self.myResultRows:
            searchLink = patentRow.findall(".//a")
    

    似乎无法实际定位链接元素。

  3. 我需要链接的纯文本。如果我首先获得了链接元素,我想它会像 searchLink.text 这样。

最后,在lxml的实际API参考文档中,我找不到有关于find和findall调用的信息。我从在谷歌上找到的代码片段中获取了这些信息。我是否忽略了使用lxml有效查找和迭代HTML标记的方法?

2个回答

27

首先,关于解析HTML:如果你遵循 zweiterlinde 和 S.Lott 的建议,至少使用包含在 lxml 中的 beautifulsoup 版本。这样你也会获得一个不错的xpath或css选择器接口。

然而,我个人更喜欢 Ian Bicking 在 lxml 中包含的HTML 解析器

其次,.find().findall() 来自于 lxml 试图兼容 ElementTree,并且这两个方法在ElementTree 中的XPath支持中有所描述。

这两个函数使用起来相当简单,但是它们在XPath方面非常受限制。我推荐尝试使用完整的lxmlxpath() 方法,或者如果您已经熟悉CSS,则使用cssselect() 方法

以下是一些示例,使用类似这样的HTML字符串解析:

from lxml.html import fromstring
mySearchTree = fromstring(your_input_string)

使用CSS选择器类,您的程序大致如下:

# Find all 'a' elements inside 'tr' table rows with css selector
for a in mySearchTree.cssselect('tr a'):
    print 'found "%s" link to href "%s"' % (a.text, a.get('href'))

使用 XPath 方法的等效方法为:

# Find all 'a' elements inside 'tr' table rows with xpath
for a in mySearchTree.xpath('.//tr/*/a'):
    print 'found "%s" link to href "%s"' % (a.text, a.get('href'))

太好了!正是我需要的。我理解cssselect实际上需要元素具有声明的CSS类。嵌套查找逻辑正是我所需要的!谢谢Van Gale! - Shaheeb Roshan
此页面建议使用iterchildren和iterdescendants选项来处理标记。http://www.ibm.com/developerworks/xml/library/x-hiperfparse/#N10239 - endolith
1
很好的回答,但是作为一个小问题——为什么使用.//tr/*/a而不是.//tr//a?前者在有额外的中间标签时无法找到任何内容,例如<tr><td><i><a href="...">..</a></i></td></tr> - Charles Duffy

5

您的项目为什么不使用Beautiful Soup?它可以更轻松地处理格式不完整的文档。


2
我最开始尝试使用Beautiful Soup,但是没有成功。我在问题中提到我的文档格式相当完整,但是缺少结束body块,在解析器中将其提取时会简单地丢弃所有内容。因此选择了lxml。另外,http://tinyurl.com/37u9gu 指出在lxml中具有更好的内存管理。 - Shaheeb Roshan
7
我最初使用了BeautifulSoup,但它声称能够处理不良HTML的能力并不像它所说的那样好。而且它也不支持具有多个类等特性的项。对于我所做的一切,lxml.html更加出色。 - endolith
11
BeautifulSoup不再维护,比lxml慢且功能不如lxml强大。 - Humphrey Bogart
2
@BeauMartínez:我知道这篇帖子已经有一年了,但为了让用户保持最新资讯:BS目前确实得到维护,并且最近甚至发布了一个新版本。根据您使用的构造函数参数,它会在内部使用lxml。 - ThiefMaster

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