2014-09-27 36 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行。

相關問題