Python html解析实际上有效

时间:2010-11-06 19:17:05

标签: python html parsing

我正在尝试用Python解析一些html。之前有一些方法确实有效......但是现在没有解决方法我就无法实际使用。

  • 在SGMLParser离开后,beautifulsoup有问题
  • html5lib无法解析“在那里”的一半
  • lxml试图对于典型的html“太正确”(属性和标签不能包含未知的命名空间,或者抛出异常,这意味着几乎没有可以解析具有Facebook连接的页面)。

这些天还有哪些其他选择? (如果他们支持xpath,那就太好了)

5 个答案:

答案 0 :(得分:20)

使用html解析HTML时,请确保使用lxml模块:

>>> from lxml import html
>>> doc = """<html>
... <head>
...   <title> Meh
... </head>
... <body>
... Look at this interesting use of <p>
... rather than using <br /> tags as line breaks <p>
... </body>"""
>>> html.document_fromstring(doc)
<Element html at ...>

所有错误&amp;异常将消失,你将留下一个惊人的快速解析器,经常处理HTML汤比BeautifulSoup更好。

答案 1 :(得分:10)

我已经在许多HTML页面抓取项目中使用了pyparsing。它是BeautifulSoup与完整HTML解析器之间的一种中间立场,以及正则表达式的过低级别方法(这种方式就是疯狂)。

通过pyparsing,您通常可以通过识别要尝试提取的页面或数据的特定子集来获得良好的HTML抓取结果。这种方法避免了尝试解析页面上所有的问题,因为您感兴趣的区域之外的一些有问题的HTML可能会抛弃一个全面的HTML解析器。

虽然这听起来只是一种美化的正则表达式方法,但是pyparsing提供了用于处理HTML或XML标记文本的内置函数。 Pyparsing避免了许多使基于正则表达式的解决方案受挫的陷阱:

  • 接受空格而不会乱丢'\ s *'遍布你的表情
  • 处理标记内的意外属性
  • 按任意顺序处理属性
  • 处理标签中的大写/小写
  • 使用命名空间处理属性名称
  • 以双引号,单引号或引号处理属性值
  • 处理空标记(形式为<blah />
  • 的标记
  • 返回已对标记属性进行对象属性访问的已分析标记数据

以下是pyparsing wiki中一个从网页获取<a href=xxx>标记的简单示例:

from pyparsing import makeHTMLTags, SkipTo

# read HTML from a web page
page = urllib.urlopen( "http://www.yahoo.com" )
htmlText = page.read()
page.close()

# define pyparsing expression to search for within HTML    
anchorStart,anchorEnd = makeHTMLTags("a")
anchor = anchorStart + SkipTo(anchorEnd).setResultsName("body") + anchorEnd

for tokens,start,end in anchor.scanString(htmlText):
    print tokens.body,'->',tokens.href

即使页面的其他部分包含有问题的HTML,也会提取<a>标记。在pyparsing wiki中还有其他HTML示例:

Pyparsing并不是解决这个问题的完全万无一失的解决方案,但通过向您展示解析过程,您可以更好地控制您特别感兴趣的HTML部分,处理它们,并跳过其余部分。

答案 2 :(得分:5)

  

html5lib无法解析“在那里”的一半

听起来非常难以置信。 html5lib使用与最近版本的Firefox,Safari和Chrome中实现的完全相同的算法。如果该算法打破了网络的一半,我想我们会听到。如果您遇到特殊问题,请提交文件错误。

答案 3 :(得分:4)

如果您正在抓取内容,那么解决烦恼细节的绝佳方法是sitescraper包。它使用机器学习来确定要为您检索哪些内容。

从主页:

>>> from sitescraper import sitescraper
>>> ss = sitescraper()
>>> url = 'http://www.amazon.com/s/ref=nb_ss_gw?url=search-alias%3Daps&field-keywords=python&x=0&y=0'
>>> data = ["Amazon.com: python", 
             ["Learning Python, 3rd Edition", 
             "Programming in Python 3: A Complete Introduction to the Python Language (Developer's Library)", 
             "Python in a Nutshell, Second Edition (In a Nutshell (O'Reilly))"]]
>>> ss.add(url, data)
>>> # we can add multiple example cases, but this is a simple example so 1 will do (I   generally use 3)
>>> # ss.add(url2, data2) 
>>> ss.scrape('http://www.amazon.com/s/ref=nb_ss_gw?url=search-alias%3Daps&field-  keywords=linux&x=0&y=0')
["Amazon.com: linux", ["A Practical Guide to Linux(R) Commands, Editors, and Shell    Programming", 
"Linux Pocket Guide", 
"Linux in a Nutshell (In a Nutshell (O'Reilly))", 
'Practical Guide to Ubuntu Linux (Versions 8.10 and 8.04), A (2nd Edition)', 
'Linux Bible, 2008 Edition: Boot up to Ubuntu, Fedora, KNOPPIX, Debian, openSUSE, and 11 Other Distributions']]

答案 4 :(得分:1)

我认为问题在于大多数HTML格式不正确。 XHTML尝试解决这个问题,但它从来没有真正流行起来 - 特别是因为大多数浏览器都会为格式错误的代码执行“智能解决方法”。

几年前,我尝试为原始的蜘蛛类应用程序解析HTML,并发现问题太难了。我怀疑写下你自己可能会在卡片上,虽然我们不能成为唯一有这个问题的人!