2014-09-27 71 views
2

我不想知道如何解决这个问题,因为我自己解决了这个问题。我只是问它是否真的是一个错误,以及我是否和如何报告它。 可以找到的代码和下面的输出:HTMLParser误解了href中的实体。这是一个错误还是不是?我应该报告吗?

from html.parser import HTMLParser 

class MyParser(HTMLParser): 
    def handle_starttag(self, tag, attrs): 
     for at in attrs: 
      if at[0] == 'href': 
       print(at[1]) 
     return super().handle_starttag(tag, attrs) 

    def handle_data(self, data): 
     return super().handle_data(data) 

    def handle_endtag(self, tag): 
     return super().handle_endtag(tag) 



s = '<a href="/home?ID=123&gt3=7">nomeLink</a>' 

p = MyParser() 
p.feed(s) 

以下是输出:

“?/家ID = 123> 3 = 7”

+0

HTML格式错误;而'&'应该转义为'&'。解析器正在尽全力修复损坏。 – 2014-09-27 09:09:07

回答

2

不,它不是一个错误。你是喂养解析器无效的HTML,包括在一个HTML属性的URL &正确的方法是将其逃脱&amp;

>>> s = '<a href="/home?ID=123&amp;gt3=7">nomeLink</a>' 
>>> p = MyParser() 
>>> p.feed(s) 
/home?ID=123&gt3=7 

解析器尽了最大的(根据需要由HTML标准)而得到您尽可能地修复了数据。在这种情况下,它试图修复另一个常见的错误HTML错误:拼写&gt;&gt(忘记;分号)。我们建议您使用BeautifulSoup来代替。 BeautifulSoup支持多个解析器,其中一些可以比其他解析器更好地处理破碎的HTML。

例如,html5lib解析器可以在属性处理转义&符号优于html.parser可以:

>>> from bs4 import BeautifulSoup 
>>> s = '<a href="/home?ID=123&gt3=7">nomeLink</a>' 
>>> BeautifulSoup(s, 'html.parser').find('a')['href'] 
'/home?ID=123>3=7' 
>>> BeautifulSoup(s, 'html5lib').find('a')['href'] 
'/home?ID=123&gt3=7' 

为了完整起见,第三支持的解析器,lxml,也处理转义&符号,就好像它们被转义:

>>> BeautifulSoup(s, 'lxml').find('a')['href'] 
'/home?ID=123&gt3=7' 

你可以使用lxmlhtml5lib直接,但随后你会放弃漂亮的高层次的API,BeautifulSoup提供。

+0

我已经尝试过寻找漂亮的肥皂来找到锚点,但它并没有在html页面中找到所有锚点,而只是第一个锚点。如果我能找到这个例子,我会发布它。也许网页往往是不正确的 – StackUser 2014-09-27 09:45:33

+0

BeatifulSoup使用'html.parser',除非你安装了lxml;单独使用'html.parser'没有意义。这样你不会得到更好的结果。对于损坏的HTML,请使用其他解析器。 'html5lib'做的最好,但速度较慢。 – 2014-09-27 10:25:31

+0

是的,网络充满了破碎的HTML,这是设置'宽容'标准的不利之处。 – 2014-09-27 10:35:28

1

的Python 3.3.2(V3.3.2,2013年5月16日,0时03分43秒)[MSC v.1600 32位(英特尔)]在Win32

让饲料S ='< PA =” & #39;” >'到MyHTMLParser:

class MyHTMLParser(HTMLParser): 
    def handle_starttag(self, tag, attrs): 
     print(attrs) 

这是合法的HTML标签,其中&#39;是'。 在这种情况下MyHTMLParser给出ATTRS:

[('a', "'")] 

这样的结果的原因是UNESCAPE功能的使用:

Lines in source file html/parser.py, class HTMLParser 
348:   if attrvalue: 
349:    attrvalue = self.unescape(attrvalue) 

其中self.unescape是一个内部辅助以除去特殊字符引用,这仅用于属性值。请参阅parser.py中的第504-532行。

相关问题