2012-03-12 103 views
1

我使用标准Python库中的ElementTree模块解析简单HTML时遇到了一些问题。这是我的源代码:Urllib与elementtree组合在一起

from urllib.request import urlopen 
from xml.etree.ElementTree import ElementTree 

import sys 

def main(): 
    site = urlopen("http://1gabba.in/genre/hardstyle") 
    try: 
     html = site.read().decode('utf-8') 
     xml = ElementTree(html) 
     print(xml) 
     print(xml.findall("a"))   
    except: 
     print(sys.exc_info()) 

if __name__ == '__main__': 
    main() 

要么失败,我得到我的控制台上的输出如下:

<xml.etree.ElementTree.ElementTree object at 0x00000000027D14E0> 
(<class 'AttributeError'>, AttributeError("'str' object has no attribute 'findall'",), <traceback object at 0x0000000002910B88>) 

所以XML确实是一个ElementTree的对象,当我们看documentation我们请参阅ElementTree类具有findall函数。额外的东西:xml.find(“a”)工作正常,但它返回一个int而不是Element实例。

所以有人可以帮我吗?我误解了什么?

回答

2

ElementTree(html)替换为ElementTree.fromstring(html),并将您的导入语句更改为from xml.etree import ElementTree

这里的问题是,ElementTree构造函数不期望一个字符串作为它的输入 - 它期望一个Element对象。函数xml.etree.ElementTree.fromstring()是从字符串构建ElementTree的最简单方法。

我猜测XML解析器不是你真正想要完成这项任务的,因为你正在解析HTML(它不一定是有效的XML)。你可能想看一看:

+0

不工作,(<类 'xml.etree.ElementTree.ParseError'>,ParseError(ExpatError( '不匹配的标签:线51,柱159',) ,),) - 虽然html的类型为'str',所以我不知道这里出了什么问题.. – wvd 2012-03-12 18:36:33

+0

@wvd:在很多情况下,HTML文件不是有效的XML。例如,HTML可以包含
而不匹配
。 ElementTree将失败,除非您给它的字符串是100%有效的XML。对于您提供的URL,它包含一个标签,其中没有“close tag”,它是有效的HTML,但不是有效的XML。 – 2012-03-12 18:39:47

+0

啊,所以这是抱怨,是有道理的!感谢你的回答。 – wvd 2012-03-12 18:41:26

0

行应该是:

xml = ElementTree(file=html) 

PS:以上将工作只有当XML是良好的结构ured。如果XML结构中存在错误或HTML错误,则会引发ParseError。

您可能会喜欢使用BeautifulSoup进行HTML解析。如果你想使用XPATH和lxml,你可能也喜欢html5lib。

它是那么容易,因为:

tree = html5lib.parse(html.content, treebuilder='lxml', namespaceHTMLElements=False) 
# the tree is a lxml object (parsed from any/bad html) supporting findall and find with xpaths