Python学习笔记(1)

之前的Python学习一直都因为各种原因断断续续的,导致学一点忘一点,最近正好空余时间比较集中,于是强迫自己系统地学一下爬虫巩固下。

编码

说到爬虫,那么肯定会涉及到网站和网页,说到网页,肯定绕不锅一个东西那就是网页编码。首先,如何查看网页编码?很简单,大多数浏览器都有开发者工具(F12),打开开发者工具,切换到console控制台,输入命令

1
document.charset

就可以查看当前浏览的网页的编码方式。

这是我的博客的编码方式,目前utf-8的编码方式还是比较普遍的

zzzain46的博客的编码方式

吾爱破解论坛采用的是GBK的编码方式

吾爱破解论坛的编码方式

而我们在浏览器中直接使用审查元素看到的则是Unicode编码的网页内容,如下图所示:

使用以下Python代码爬取的内容都是以utf-8编码的bytes对象,在打印出来的字符串前面可以看到一个b,这个b就表示这是一个bytes对象,可以理解为字符串的每个字符用于存放一个字节的二进制数据。所以打印出来的结果自然就和审查元素里看到的结果不太一样了。

1
2
3
4
import urllib.request
response = urllib.request.urlopen('https://www.52debug.cn')
html = response.read()
print(html)

总结下,因为计算机只认识0和1,所以用户的所有操作交付给计算机后都是通过转化成0和1的逻辑运算来完成的(硬件角度解释的高电平和低电平)。文本和二进制数之间的转化,就是靠编码来实现的。

一句话概括,编码就是一种协议,表示了二进制数和其他文本的对应关系。

编码

编码方式

文本内容编码方式
英文字母(26个)ASCII(一个字符用1个字节存放)
汉语字符(上千个)BG 2312(一个字符用2个字节存放)
日文字符Shfit JIS
… …… …
包含所有国家的文字Unicode(万国码,每个字符使用1~3个字节存放,比较浪费空间)

解码和编码

n6NG3n.png

A编码 -> decode(A) -> Unicode -> encode(B) -> B 编码

Python2和Python3的编码方式对比

Python2:默认使用ASCII编码

python2.png

Python3:默认使用utf-8

python3.png

常见问题

问题1:普通字符串和 Unicode 字符串进行拼接抛出 UnicodeDecodeError 异常(Python2)
1
2
3
4
>>> string = "我爱" + u"Fish"
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
UnicodeDecodeError: 'ascii' codec can't decode byte 0xe6 in position 0: ordinal not in range(128)
分析:

使用 + 号进行字符串拼接,左边是普通字符串,右边是 Unicode 字符串。当两种类型的字符串拼接的时候,Python 会自动将左边的中文字符串转换为 Unicode 字符串,再进行拼接操作。但由于 “我爱” 的 ASCII 编码'\xe6\x88\x91\xe7\x88\xb1',其中十六进制 '\xe6' 对应的值是 230。当编码值在 0 ~ 127 的时候,UnicodeASCII 是兼容的,转换不会有问题。但当值大于 128 的时候,ASCII 编码便不能直接转换为 Unicode 了。因此,抛出 UnicodeDecodeError

前面提到,Unicode被称为万国码,无论哪个国家的语言,都可以在 Unicode 上找到对应的代码。因此,当不同的编码系统进行相互转换的时候,可以利用 Unicode 做一个“中介”。

问题2:文件编码与 Python 编码不同

test.txt 内容如下,并保存为 GB2312 编码:

1
吾爱修霸哥,真的!

test.py 内容如下:

1
2
3
f1 = open("test.txt")
print(f1.read())
f1.close

代码执行后会报错:

1
2
3
4
5
6
7
>>> 
Traceback (most recent call last):
File "/Users/zzzain46/Documents/Python/test.py", line 4, in <module>
print(f1.read())
File "/Library/Frameworks/Python.framework/Versions/3.4/lib/python3.4/encodings/ascii.py", line 26, in decode
return codecs.ascii_decode(input, self.errors)[0]
UnicodeDecodeError: 'ascii' codec can't decode byte 0xce in position 0: ordinal not in range(128)
分析:

使用 open 打开文件的编码格式取决于系统(可以通过 locale.getpreferredencoding() 获得)仔细看报错信息,这里系统使用 ASCII 对文件内容进行解码,遇到错误······因为我们知道文件的存放格式是 GB2312,因此我们只需要在打开文件的时候设置 encoding="gb2312" 即可解决问题:

1
2
3
f1 = open("test.txt", encoding="gb2312")
print(f1.read())
f1.close

本文标题:Python学习笔记(1)

文章作者:zzzain46

发布时间:2019年09月14日 - 11:09

最后更新:2019年10月20日 - 13:10

原始链接:https://www.52debug.cn/posts/db9be8e8.html

许可协议: 署名-非商业性使用-禁止演绎 4.0 国际 转载请保留原文链接及作者。

如果你觉得我的文章对你有用,请随意打赏!
0%