Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/336.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python BeautifulSoup解析器会将分号附加到裸符号上,从而破坏URL?_Python_Beautifulsoup - Fatal编程技术网

Python BeautifulSoup解析器会将分号附加到裸符号上,从而破坏URL?

Python BeautifulSoup解析器会将分号附加到裸符号上,从而破坏URL?,python,beautifulsoup,Python,Beautifulsoup,我试图用python解析一些站点,其中包含指向其他站点的链接,但是是纯文本,而不是“a”标记。使用BeautifulSoup我得到了错误的答案。考虑这个代码: import BeautifulSoup html = """<html> <head> <title>Test html</title> </head> <body>

我试图用python解析一些站点,其中包含指向其他站点的链接,但是是纯文本,而不是“a”标记。使用BeautifulSoup我得到了错误的答案。考虑这个代码:

import BeautifulSoup

html = """<html>
            <head>
              <title>Test html</title>
            </head>
            <body>
              <div>
                example.com/a.php?b=2&c=15
              </div>
            </body>
          </html>"""

parsed = BeautifulSoup.BeautifulSoup(html)
print parsed
导入美化组
html=”“”
测试html
example.com/a.php?b=2&c=15
"""
parsed=BeautifulSoup.BeautifulSoup(html)
打印解析
当我运行上述代码时,我得到以下输出:

<html>
  <head>
    <title>Test html</title>
  </head>
  <body>
    <div>
      example.com/a.php?b=2&c;=15
    </div>
  </body>
</html>

测试html
example.com/a.php?b=2&c=15

注意“div”中的链接和部分b=2&c=15它与原始HTML不同。为什么美联会以这种方式搅乱链接呢。它是否试图自动创建HTML实体?如何防止这种情况发生?

很明显,英国广播公司(BS)有一个文档不足的地方,我只是在他们的讨论论坛上搜索“分号”。根据2009年的讨论,裸
&
严格来说是无效的,必须用
&虽然浏览器接受这一点,所以它看起来很迂腐

我同意这种解析行为是假的,您应该联系他们的列表,要求他们至少将其作为已知问题更好地记录下来,并在将来修复它

变通方法:无论如何,您的变通方法很可能是
re.sub(…)
捕获并展开
&
->
&仅在URL内部。您可能需要一个反向函数来在输出中压缩它们。您需要一个更高级的正则表达式来捕获URL中的符号,但无论如何:

# Minimal string to tickle this
#html = "<html>example.com/a.php?b=2&c=15&d=42</html>"
html = "<html>example.com/a.php?b=2&c=15&amp;d=29&e=42</html>"

html = re.sub(r'&(?!amp;)', r'&amp;', html)

parsed = BeautifulSoup.BeautifulSoup(html)
>>> print parsed.text.encode('utf-8')
'example.com/a.php?b=2&amp;c=15'

>>> re.sub(r'&amp;', r'&', parsed.text.encode('utf-8'))
'example.com/a.php?b=2&c=15'
#最小的字符串来逗乐这个
#html=“example.com/a.php?b=2&c=15&d=42”
html=“example.com/a.php?b=2&c=15&d=29&e=42”
html=re.sub(r'&(?amp;)',r'&;',html)
parsed=BeautifulSoup.BeautifulSoup(html)
>>>打印已解析的.text.encode('utf-8')
'example.com/a.php?b=2&;c=15'
>>>re.sub(r'&;',r'&',parsed.text.encode('utf-8'))
'example.com/a.php?b=2&c=15'
可能还有其他更具理性的方法。
您可能希望帮助测试4.0 beta版。

建议您将标题更改为“BeautifulSoup parser将分号附加到裸符号,弄乱URL”。问题是如果使用了其他实体;e、 g.如果我有
&trade,或已转义的
&,它们将显示为
&trade
&而不是
&
。理想情况下,您需要一个否定的先行断言来检查它是否是一个有效的实体。@Chris:好的,我添加了否定的先行断言。(不过正则表达式仍然需要代码来匹配URL。)我和@ChrisMorgan有着相同的想法。我检查发现实体可以在2到8个字符之间,所以我在测试中将其缓冲到9:
re.sub(r'&(?[a-zA-Z0-9]{2,9}'),r'&;,html)
@RichardBronosky:这可以处理普通的html,但如果处理任何XML,长度断言肯定不会成立(关于潜在字符的断言也不重要)。例如,在Firefox的XUL中,您经常会得到相当长的实体(它们用于翻译),例如about:robots中的
robots.pagetitle
。@ChrisMorgan,很高兴知道。如果我处理非html,我会尽量小心。谢谢。