爬虫中的那些编码问题

前言

近日一直在爬虫学习的路上摸打滚爬,问题接踵而来,就在今天遇见了编码的问题,苦不堪言,苦苦需求“真相”,有所心得,分享一下,寻求同辈之人,聊以自慰。

问题

爬虫的学习终于到了进程这一关,我按照书上的代码进行测试,不料给出的网站还在“月球“呆着,于是随手点了另外一个网站进行测试。通过源码审计,发现需要的内容在标签的属性中,于是决定使用xpath来攻克它。内心激动而面无表情的按下快捷键,看着打印出的数据,我心甚慰,却不料突然中断,报错提醒。我早已轻车熟路,百度一下:

UnicodeDecodeError: 'utf-8' codec can't decode byte 0xf4 in position 26: invalid continuation byte

翻译
UnicodeDecodeError:“utf-8”编解码器无法解码位置26中的字节0xf4:无效的连续字节

通过取经,我尝试更改代码

res = res.content
html = res.decode("utf-8”)

text格式是我们可读的文本形式,content是二进制的形式,使用decode再将其转化为utf-8可读的文本。
执行代码,新的问题来了

UnicodeDecodeError: 'utf-8' codec can't decode byte 0xf4 in position 26: invalid continuation byte

翻译
UnicodeDecodeError:“utf-8”编解码器无法解码位置26中的字节0xf4:无效的连续字节

有点崩溃,还能怎么办,继续查,总结了三种看似能解决问题的方法:

  1. 爬取的内容中有的字符不在utf-8的编码范围中,换一个收录范围更大的编码,例如:gb2312,gbk等
  2. 添加部分内容,例如: decode(‘utf-8’, ‘ignore’),这样遇到无法识别的字符便会跳过
  3. 爬取的内容中含有非法字符,找到它删除

第一种方法,我尝试过后并没有成功,至于第三种,我编写爬虫循环爬取内容,再去更改,自然不妥当,所以使用了第二种方式。

我就知道问题没有那么简单,代码执行成功,但是爬取出的内容全部乱码,无法识别。此刻的我有种上天无门的感觉,我明白必须去好好学习一下编码的知识。

编码

众所周知,计算机的母语是英语,所以最初的计算机字符编码是通过ASCII来编码,它包含字母,数字,标点符号以及一些特殊字符,完全满足使用英语的国家的需求。

后来计算机不断发展,世界上越来越多的国家开始普及,许多国家拥有自己语言,单纯的ASCII无法满足这些国家的需求,于是出现了Unicode编码。Unicode由两个字节组成,共表示256*256个字符,即UCS-2,生僻字甚至用到四个字符,基本满足了不同国家的需求。

Unicode的出现是很大的进步,但对于使用英语的国家来说并不美好,原来一个字节就可以完成的事,现在要两个甚至更多,浪费了资源。utf-8由此诞生,utf-8可以从一个字节到多个字节的伸缩,还兼容ASCII,灵活强大。

前面的编码再好,终究是别人国家的,所以我国也制定了自己的标准:GB2312,GBK,收录的中文字符更多,更强大,但是现在常用的还是utf-8,比如我们使用的python,默认便是utf-8。


编码相关的知识学习完毕,我也有一个大体的认识,再回到我们的问题
import sys

print(sys.getdefaultencoding())

上面的代码可以显示我们使用的默认编码为utf-8,也就是说再最开始写的爬虫中,我们都是使用utf-8编码来输出我们的获取的数据

那么我们爬取的网站的默认编码是什么?

print(res.encoding)
print(res.apparent_encoding)

如果header中存在charset字段,说明我们访问的服务器对它资源的编码方式是有要求的。可以使用r.encoding 来获取。

如果header中不存在charset字段,则认为默认编码为ISO-8859-1,但是这个编码不能解析中文。

r.apparent_encoding:根据网页内容分析出的编码方式。

后者更加可靠,我得到的两个编码分别为:gb2312,GB2312,一样,所以我思考使用encode将爬取的文本先解码再使用utf-8编码,也许可以解决问题,但是还是乱码问题。
最终我设置了一个判断,只有r.encoding获取的编码为GB2312,才执行下面的步骤,没有报错,勉强结局。

虽然程序不在报错,但是还有纰漏,网站的每一页并非都是GB2312编码,所以有的网页无法爬取,如果哪位大佬结局了我的问题,希望不吝赐教。另外我们再搭建网站是,一定要规范啊,不然太难为人了。

后记

这次的问题并没有完美结局,总有一点遗憾,以后技术更强时,再回来解决。

你可能感兴趣的:(python爬虫)