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;&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'

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

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

你可以直接使用lxmland html5lib,但是你会放弃 BeautifulSoup 提供的漂亮的高级 API。

于 2014-09-27T09:15:51.283 回答
1

Python 3.3.2(v3.3.2,2013 年 5 月 16 日,00:03:43)[MSC v.1600 32 位(英特尔)] 在 win32 上

让 s = '<pa="'">' 给 MyHTMLParser:

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

这是有效的 html 标记,其中 ' 是为了'。在这种情况下,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 行。

于 2015-02-25T20:35:29.837 回答