我决定学习C ++,我非常喜欢网站www.learncpp.com。 现在,我想制作一个pdf版本并打印出来,以便我可以在纸上阅读。首先,我建立了网站所有章节的网址收集器。它工作正常。
现在我正在努力从first chapter创建一个html。我写了以下内容:
import requests
from bs4 import BeautifulSoup
import codecs
req = requests.get("http://www.learncpp.com/cpp-tutorial/01-introduction-to-these-tutorials/")
soup = BeautifulSoup(req.text,'lxml')
content = soup.find("div", class_="post-9")
f = open("first_lesson.html","w")
f.write(content.prettify().encode('utf-8'))
f.close()
我在文件夹中找到了first_lesson.html
文件。
问题是,当我打开html文件来检查结果时,会出现奇怪的符号(尝试运行代码并查看)。
我添加了.encode('utf-8')
,否则我会收到错误:
UnicodeEncodeError: 'ascii' codec can't encode character u'\u2014' in position 155: ordinal not in range(128)
如何消除那些奇怪的符号?什么是正确的编码? 而且,如果我将来遇到类似的问题,我怎么知道什么是正确的编码?
UPDATE :而不是'utf-8'中的编码,我在'windows-1252'中进行了编码,而且工作正常。但了解如何正确编码的最佳策略是什么?因为我不认为尝试这个尝试 - 这是一个很好的
答案 0 :(得分:1)
在python2中使用请求时,您应该使用.content
让请求处理编码,您可以使用io.open写入文件:
import requests
from bs4 import BeautifulSoup
import io
req = requests.get("http://www.learncpp.com/cpp-tutorial/01-introduction-to-these-tutorials/")
soup = BeautifulSoup(req.content, 'lxml')
content = soup.find("div", class_="post-9")
with io.open("first_lesson.html", "w") as f:
f.write(soup.prettify())
如果您确实要指定编码,则美化采用编码参数soup.prettify(encoding=...)
,还有编码属性:
enc = req.encoding
您可以解析尝试使用cgi.parse_headers解析标题:
import cgi
enc = cgi.parse_header(req.headers.get('content-type', ""))[1]["charset"]
或尝试安装并使用chardet模块:
import chardet
enc = chardet.detect(req.content)
您还应该知道,许多编码可能会运行而不会出现错误,但您最终会在文件中出现垃圾。 charset设置为utf-8,您可以在返回的标题中看到它,如果您查看源代码,则可以看到<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
。
答案 1 :(得分:0)
content.prettify()
是一个unicode字符串。碰巧其中包含代码点U + 2014,它映射到角色 - (EM DASH)。 ASCII编解码器无法对其进行编码,因为8212 = 0x2014大于127。
但是,您可以使用任何可以处理unicode代码点的编码对您的unicode字符串进行编码,例如utf-16,utf-32,ucs-2,ucs-4或ucs-8。没有“正确”的编码,但utf-8是他们的王者,所以通常它是一个很好的选择,当你想编码一个unicode字符串,但你可以选择另一个(python支持)和 你的程序 - 例如 - 也可以与
一起使用f.write(content.prettify().encode('utf-16'))
prettify
为你提供了一个unicode字符串,默认情况下尝试使用utf-8进行解码(这是我从查看源代码时理解的),但你可以给prettify
一个明确的编码作为一个论点工作。将unicode字符串视为一种抽象,一系列unicode代码点基本上对应于一系列字符(这些字符只是小图像)。
如果您需要使用beautifulsoup查找HTML文档的内容类型,可能会发现this和this问题有用。
另一点:一般来说,每当你有普通字节并且没有人告诉你它们应该如何被解码时,你就不走运了,不得不玩傻瓜。如果你知道你正在处理文本,utf-8通常是一个很好的第一个猜测,因为它是a)广泛使用和b)前128个unicode字符与ASCII一对一对应,utf-8用它们编码它们相同的字节值。
您可能还会发现来自PyCon 2012的this chartable和this对话很有用。