编解码
编码的由来:计算机只能计算和识别二进制,必须让计算机识别文字,才能和计算机进行交互,彼此也才能通过计算机通信。由此,有了ASCII编码的诞生,它起始于50年代后期,在1967年定案,是最初美国国家标准,供不同计算机在相互通信时用作共同遵守的西文字符编码标准。
ASCII编码: 八位二进制最多可以表示的十进制数字范围是,0000 0000 ~ 1111 1111 = 0 ~ 255 ,一共256个不同数字。ASCII编码就是将常用的英文字符和符号,与256个数字逐一对应起来形成的对应表。由于计算机是美国人发明的,因此,最早只有127个字母被编码到计算机里,也就是大小写英文字母、数字和一些符号,这个编码表被称为ASCII编码;后来又扩展了128个,称为扩展ASCII码。例如:十进制33对应叹号!,65对应大写A,83对应大写S,97对应小写a,这样我们输入字符,计算机转换成十进制,再转换成二进制,就可以通过计算机计算或传输。
字节: 中英文都需要断句才能明确含义,二进制也一样。一串二进制数字,没有规定开头结尾,是无法准确识别转换成十进制,从而对应编码找出对应字符的。
编码集的演变:
由于计算机是美国人发明的,因此,最早只有127个字符被编码到计算机里,也就是大小写英文字母、数字和一些符号,这个编码表被称为ASCII编码,比如大写字母A的编码是65,小写字母z的编码是122。但是要处理中文显然一个字节是不够的, 至少需要两个字节,而且还不能和ASCII编码冲突,所以,中国制定了GB2312编码,用来把中文编进去。你可以想得到的是,全世界有上百种语言,日本把日文编到Shift_ _JIS里,韩国把韩文编到Euc-kr里,各国有各国的标准,就会不可避免地出现冲突,结果就是,在多语言混合的文本中,显示出来会有乱码。因此,Unicode应运而生。Unicode把所有语言都统一到- 套编码里,这样就不会再有乱码问题了。Unicode标准也在不断发展,但最常用的是用两个字节表示一个字符(如果要用到非常偏僻的字符,就需要4个字节)。现代操作系统和大多数编程语言都直接支持Unicode。
(一)get请求方式
1.1 urllib.parse.quote()
将汉字变为Unicode编码
eg:在百度上搜易烊千玺,它的url地址为https://www.baidu.com/s?wd=%E6%98%93%E7%83%8A%E5%8D%83%E7%8E%BA,而参数易烊千玺的Unicode编码就是%E6%98%93%E7%83%8A%E5%8D%83%E7%8E%BA。若以中文形式爬取该网页源码,则会报错如下图:
而urllib.parse.quote()方法正是为了解决此问题而生。
语法如下:
例:
import urllib.request import urllib.parse # https://www.baidu.com/s?wd=%E6%98%93%E7%83%8A%E5%8D%83%E7%8E%BA url = 'https://www.baidu.com/s?wd=' name = urllib.parse.quote('易烊千玺') print(name)
运行结果:
这里可以看出已经将汉字转变为了Unicode编码格式!
下面我们来看实例(获取百度搜索易烊千玺的网页源码):
import urllib.request import urllib.parse # https://www.baidu.com/s?wd=%E6%98%93%E7%83%8A%E5%8D%83%E7%8E%BA url = 'https://www.baidu.com/s?wd=' headers = { 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.25 Safari/537.36 Core/1.70.3880.400 QQBrowser/10.8.4554.400' } # 获取ua标识 # 将易烊千玺变为Unicode编码形式。 name = urllib.parse.quote('易烊千玺') # 合并url url = url + name # 定制请求对象 request = urllib.request.Request(url = url , headers = headers) # 模拟浏览器向服务器发送请求 response = urllib.request.urlopen(request) # 获取响应内容 content = response.read().decode('utf-8') # 打印数据 print(content)
运行结果:
1.2 urllib.parse.urlencode()
为了更方便快捷的解决url中多个参数的问题。urllib.parse.urlencode() 可以将字典里的各个数据使用与的连接符来合并,并且转换为Unicode编码格式。
例如:
import urllib.parse # https://www.baidu.com/s?wd=%E6%98%93%E7%83%8A%E5%8D%83%E7%8E%BA&sex=%E7%94%B7 url = 'https://www.baidu.com/s?wd=易烊千玺&sex=男' data = { 'wd':'易烊千玺', 'sex':'男' } a = urllib.parse.urlencode(data) print(a)
运行结果:
下面我们来看下实例(爬取百度搜索易烊千玺(wd=“易烊千玺”&sex=“男”)):
import urllib.request import urllib.parse # https://www.baidu.com/s?wd=%E6%98%93%E7%83%8A%E5%8D%83%E7%8E%BA&sex=%E7%94%B7 url = 'https://www.baidu.com/s?' headers = { 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.25 Safari/537.36 Core/1.70.3880.400 QQBrowser/10.8.4554.400' } data = { 'wd':'易烊千玺', 'sex':'男' } a = urllib.parse.urlencode(data) url = url + a # 定制请求对象 request = urllib.request.Request(url = url , headers = headers) # 模拟浏览器向服务器发送请求 response = urllib.request.urlopen(request) # 获取响应数据 content = response.read().decode('utf8') # 打印数据 print(content)
运行结果:
(二) post请求方式
注意事项:
post请求需要的是字节型,一定要进行编码。
编码之后必须调用encode方法
参数是放在请求对象定制的方法中
# post 请求的参数一定要进行编码 data = urllib.parse.urlencode(data).encode('utf8')
实例1(百度翻译):
import urllib.request import urllib.parse import json url = 'https://fanyi.baidu.com/sug' headers = { 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.25 Safari/537.36 Core/1.70.3880.400 QQBrowser/10.8.4554.400' } data = { 'kw':'spider' } # post 请求的参数一定要进行编码 data = urllib.parse.urlencode(data).encode('utf-8') # post 的请求参数是不会拼接在url后面的,而是放在请求对象的参数中 request = urllib.request.Request(url = url ,data = data ,headers = headers) # 模拟浏览器向服务器发送请求 response = urllib.request.urlopen(request) content = response.read().decode('utf8') # 将字符串转变为json类型 obj = json.loads(content) print(obj)
运行结果:
实例2(百度翻译之详细翻译):
在这里可以看出案例1和案例2 两者的差距,在这里我们将可以了解到反爬虫的第二个策略(Cookie反爬)
代码如下:
import urllib.request import urllib.parse import json url = 'https://fanyi.baidu.com/v2transapi?from=en&to=zh' headers = { 'Cookie': 'PSTM=1644824903; BAIDUID=DC45D78727F6132FA71DB5361C5EB5EB:FG=1; BIDUPSID=77208210F2997672227A0629541168C4; BDORZ=B490B5EBF6F3CD402E515D22BCDA1598; REALTIME_TRANS_SWITCH=1; FANYI_WORD_SWITCH=1; HISTORY_SWITCH=1; SOUND_SPD_SWITCH=1; SOUND_PREFER_SWITCH=1; APPGUIDE_10_0_2=1; __yjs_duid=1_e35e59a720afcbb8f04f6ab3797ae51b1645353651180; Hm_lvt_64ecd82404c51e03dc91cb9e8c025574=1645358868,1645358877,1645359198,1645359479; Hm_lpvt_64ecd82404c51e03dc91cb9e8c025574=1645359479; ab_sr=1.0.1_Njc3NTRlMGI4YmNhNWNmNjE2N2JiZmFhYmY1Y2ExZWVmMmI0ZDYxNzQ1OTVhMWFhNmJhOTEwYjViZjc1ZmQ1NjVkYzA4MGNmMjA3NmRmN2NhYzY4ZjA3Y2I3MTcyZmQxZTYwMDRhN2JlYzk2ODFiM2VkYjBlZDA4Y2NiMzhiM2VkYjhiNmE2NTA3NTA5ODNiMzRiZmY2ZjgxNTZhMWY4Ng==; H_PS_PSSID=31254_26350; BDRCVFR[Zrmb_XaMrqn]=pdg3iqubLhtTvqMULR8mvqV; BA_HECTOR=2kag2g018k0g0k8hq71h14ci10r' } data = { 'from': 'en', 'to': 'zh', 'query': 'location', 'transtype': 'realtime', 'simple_means_flag': '3', 'sign': '475759.237918', 'token': '574523c4a4f070313720caee427fc860', 'domain': 'common' } data = urllib.parse.urlencode(data).encode('utf-8') # 定制请求对象 request = urllib.request.Request(url = url ,data = data ,headers = headers) # 模拟浏览器向服务器发送请求 response = urllib.request.urlopen(request) # 返回响应数据 content = response.read().decode('utf-8') # 将字符串类型转换为json类型 obj = json.loads(content) print(obj)
运行结果:
以上就是get请求和post请求的全部内容了。有什么不足的地方可以在评论区提哦,希望大家可以多多关注我,期待后续!!