您犯了两个错误;您对编码的处理不当,并且将结果列表视为可以安全地转换为字符串而不丢失信息的内容。
首先,不要使用response.text
!此处不是BeautifulSoup错误,您正在重新编码Mojibake。当服务器未明确指定编码时,该requests
库将对text/*
内容类型默认使用Latin-1编码,因为HTTP标准指出这是默认设置。
唯一的一次请求不会做到这一点,如果没有明确的字符集是存在于HTTP头 ,并 在Content-Type
头中包含text
。。在这种情况下,请求遵循规范。如果需要其他编码,则可以手动设置Response.encoding
属性,或使用rawResponse.content
。
大胆强调我的。
传递response.content
原始数据:
soup = BeautifulSoup(r.content)
我看到您使用的是BeautifulSoup3。您确实想升级到BeautifulSoup 4。第3版已于2012年停产,并包含多个错误。安装beautifulsoup4
项目,并使用from bs4 import BeautifulSoup
。
BeautifulSoup 4通常可以很好地找出解析时使用的正确编码,无论是从HTML<Meta>
标记还是对提供的字节进行统计分析。如果服务器确实提供了字符集,您仍然可以从响应中将其传递给BeautifulSoup,但是如果requests
使用默认值,请首先进行测试:
encoding = r.encoding if 'charset' in r.headers.get('content-type', '').lower() else None
soup = BeautifulSoup(r.content, from_encoding=encoding)
最后但并非最不重要的一点是,使用BeautifulSoup 4,您可以使用soup.get_text()
以下命令从页面中提取所有文本:
text = soup.get_text()
print text
您正在将 结果列表 (的返回值soup.findAll()
)转换为字符串。这永远都行不通,因为Python中的容器会在repr()
列表中的每个元素上使用以生成调试字符串 ,对于字符串而言,这意味着您会获得所有非可打印ASCII字符的转义序列。