一般情况下,不要使用r.content(接收到的字节串),而是使用r.text,它是使用requests确定的编码解码的内容。
在这种情况下,requests 将使用 UTF-8 解码传入的字节字符串,因为这是服务器在 Content-Type 标头中报告的编码:
import requests
r = requests.get('http://fm4-archiv.at/files.php?cat=106')
>>> type(r.content) # raw content
<class 'bytes'>
>>> type(r.text) # decoded to unicode
<class 'str'>
>>> r.headers['Content-Type']
'text/html; charset=UTF-8'
>>> r.encoding
'UTF-8'
>>> soup = BeautifulSoup(r.text, 'lxml')
这将解决“Wildlöwenpfleger”问题,但是页面的其他部分随后会开始中断,例如:
>>> soup = BeautifulSoup(r.text, 'lxml') # using decoded string... should work
>>> soup.find_all('a')[39]
<a href="details.php?file=1882">Der Wildlöwenpfleger</a>
>>> soup.find_all('a')[10]
<a href="files.php?cat=87" title="Stermann und Grissemann sind auf Sommerfrische und haben Hermes ihren Salon �bergeben. Auf Streifz�gen durch die Popliteratur st��t Hermes auf deren gro�e Themen und h�rt mit euch quer. In der heutige">Salon Hermes (6 files)
显示“Wildlöwenpfleger”已修复,但现在“übergeben”和第二个链接中的其他内容已损坏。
似乎在一个 HTML 文档中使用了多种编码。第一个链接使用UTF-8编码:
>>> r.content[8013:8070].decode('iso-8859-1')
'<a href="details.php?file=1882">Der Wildlöwenpfleger</a>'
>>> r.content[8013:8070].decode('utf8')
'<a href="details.php?file=1882">Der Wildlöwenpfleger</a>'
但第二个链接使用 ISO-8859-1 编码:
>>> r.content[2868:3132].decode('iso-8859-1')
'<a href="files.php?cat=87" title="Stermann und Grissemann sind auf Sommerfrische und haben Hermes ihren Salon übergeben. Auf Streifzügen durch die Popliteratur stößt Hermes auf deren große Themen und hört mit euch quer. In der heutige">Salon Hermes (6 files)\r\n</a>'
>>> r.content[2868:3132].decode('utf8', 'replace')
'<a href="files.php?cat=87" title="Stermann und Grissemann sind auf Sommerfrische und haben Hermes ihren Salon �bergeben. Auf Streifz�gen durch die Popliteratur st��t Hermes auf deren gro�e Themen und h�rt mit euch quer. In der heutige">Salon Hermes (6 files)\r\n</a>'
显然在同一个 HTML 文档中使用多种编码是不正确的。除了联系文档的作者并要求更正之外,您可以轻松地处理混合编码。也许您可以在处理数据时对数据运行chardet.detect(),但这并不令人愉快。