我正在尝试解析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>
<head>
<title>Test html</title>
</head>
<body>
<div>
example.com/a.php?b=2&c;=15
</div>
</body>
</html>
注意“div”中的链接和b = 2&amp; c; = 15的部分。它与原始HTML不同。为什么BeautifulSoup会以这种方式搞乱链接。它是否试图自动创建HTML entites?如何防止这种情况?
答案 0 :(得分:7)
显然,BS有一个未记录的issue parsing ampersands inside URL,我只是在他们的讨论论坛上搜索了'分号'。根据2009年的讨论,裸&
严格无效,必须由&
替换,尽管浏览器接受这一点,所以它看起来很迂腐。
我同意这种解析行为是假的,您应该联系他们的列表,要求他们至少将此更好地记录为已知问题,并在将来修复它。
解决方法:无论如何,您的解决方法很可能是re.sub(...)
来捕获和展开&
- &gt; &
仅在内部网址中。可能你需要一个反向函数来在输出中压缩它们。您需要一个更高级的正则表达式来捕获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&d=29&e=42</html>"
html = re.sub(r'&(?!amp;)', r'&', html)
parsed = BeautifulSoup.BeautifulSoup(html)
>>> print parsed.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'
可能还有其他更多的BS-thonic方法。 您可能想帮助测试4.0 beta。