2

自分で解決したので、問題の解決方法を知りたくありません。それが本当にバグなのか、それを報告すべきかどうか、どのように報告すべきかを尋ねているだけです。以下のコードと出力を見つけることができます。

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)

出力は次のとおりです。

"/home?ID=123>3=7"

4

2 に答える 2

3

いいえ、バグではありません。パーサーに無効な 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;as (セミコロンを&gt忘れた)。;

html.parser自分で (かなり低レベルの) ライブラリの上に構築するのではなく、代わりに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'

完全を期すために、サポートされている 3 番目のパーサーlxmlも、エスケープされていないアンパサンドをエスケープされているかのように処理します。

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

lxmland を直接使用することもできますhtml5libが、それでは BeautifulSoup が提供する優れた高レベル API を忘れてしまいます。

于 2014-09-27T09:15:51.283 に答える