回顾cookie和session
requests库的介绍
requests库基于上一篇学习的urllib库,但是比urllib库更加简单,优雅,使用起来更加方便。
Requests是一个优雅而简单的python http库,是有史以来下载次数最多的python软件包之一,每天下载量超过400,000次。
之前的urlib库作为python的标准库,因为历史原因,使用的方式非常麻烦而复杂,而且官方文档也十分简陋。常常需要去查看源码。与之相反的是,Requests的使用方式非常简单、直观、人性化,让程序员的精力完全从库的使用中解放出来。
Requests的官方文档也非常完善详尽。
requests最大的特性就是其风格的简单,直接,优雅。无论是请求方法,还是响应结果的处理,还有cookies,url参数,post提交数据,都体现出了这种风格。
下面给出一个直观的代码印象:
requests目前基本上完全满足web请求的所有需求,以下是requests的特性:
- Keep-Alive & 连接池
- 国际化域名和URL
- 带持久Cookie的会话
- 浏览器式的SSL认证
- 自动内容解码
- 基本/摘要时的身份认证
- 优雅的 key/value Cookie
- 自动解压
- Unicode 响应体
- HTTP(S) 代理支持
- 文件分块上传
- 流下载
- 连接超时
- 分块请求
- 支持 .netrc
requests库发送请求
requests的请求不再像urllib一样需要去构造各种Request、opener和handler,使用requests构造的方法,并在其中传入需要的参数即可。
每一个请求方法都有一个对应的API,比如GET请求就可以使用get()方法:
import requests
resp = requests.get("http://baidu.com")
而POST请求就可以使用post()方法,并且将需要提交的数据传递给data参数即可:
import requests
resp = requests.post("http://httpbin.org/post",data = {"key":"value"})
而其他的请求类型,都有各自对应的方法
>>> resp = requests.put("http://httpbin.org/put",data={"key":"value"})
>>> resp = requests.delete("http://httpbin.org/delete")
>>> resp = requests.head("http://httpbin.org/get")
>>> resp = requests.options("http://httpbin.org/get")
可以直接在方法中传递表单参数,url参数,请求头,cookies
import requests
# response = requests.get('http://httpbin.org/get')
# response.encoding = 'utf-8'
# print(response.text)
info = { #表单参数
'username':'wgdh',
'password':'123456'
}
args = { #url参数
'key1':'value1',
'key2':'value2'
}
headers = { #headers 参数
'key':'value'
}
co = { #自定义 cookies
'session_id':'123456',
'username':'wgdh',
'password':'123456'
}
resp = requests.post('http://httpbin.org/post',data=info,params=args,headers=headers,cookies=co)
print(resp.request.url)
print(resp.url) ##上条语句的简单形式
print(resp.text)
# 请求头是请求头,响应头是响应头
print(resp.request.headers)
设置代理
当我们需要使用代理时,同样构造代理字典,传递给proxies参数
import requests
proxy = {
'http':'http://182.61.29.114:6868'
}
response = requests.get('http://httpbin.org/ip',proxies=proxy)
print(response.text)
重定向
在网络请求中,我们常常会遇到状态码是3开头的重定向问题,在requests中是默认开启允许重定向的,即遇到重定向时,会自动继续访问。
import requests
resp = requests.get('http://github.com',allow_redirects=False)
print(resp.url)
print(resp.headers)
禁止证书验证
有时我们使用了抓包工具,这个时候由于抓包工具提供的证书并不是由受信任的数字证书颁发机构颁发的,所以证书的验证就会失败,所以我们就需要关闭证书验证。
在请求的时候把verify参数设置为False就可以关闭证书验证了
import requests
resp = requests.get('https://quanshuwang.com',verify=False)
print(resp.text)
设置超时
设置访问时间的时间限制
import requests
resp = requests.get('https://github.com',timeout=1)
print(resp.text)
requests库 接收响应
通过requests发起请求获取到的,是一个requests.models.Response对象。通过这个对象我们可以很方便的获取响应的内容。
之前通过urlllib获取的响应,读取的内容都是bytes的二进制格式,需要我们自己去将结果decode()一次转换成字符串数据。
而requests通过text属性,就可以获得字符串格式的响应内容。
字符编码
requests会自动的根据响应的报头来猜测网页的编码是什么,然后根据猜测的编码来解码网页内容,基本上大部分的网页都能够正确被解码。而如果发现text解码不正确的时候,就i需要我们自己手动去指定解码的编码格式
resp.encoding="utf-8"
中文编码:gbk,gb2312
如果需要获得原始的二进制数据,那么使用content属性即可
resp.content
因此如果想要下载图片,可以使用requests简单操作:
import requests
resp=requests.get('图片链接地址')
with open('test.jpg','wb') as f:
f.write(resp.content)
json数据
如果我们访问之后获得的数据是json格式的,那么我们可以使用json()方法,直接获取转换成字典格式的数据
import requests
resp = requests.get('http://httpbin.org/get')
print(resp.json())
print(type(resp.json()))
print(resp.json()['url'])
状态码
通过status_code属性可以获取响应的状态码
resp = requests.get('http://httpbin.org/get')
print(resp.status_code)
Session对象
在requests中,实现了Session(会话)功能,当我们使用Session时,能够像浏览器一样,在没有关闭浏览器时,能够保持住访问的状态。
这个功能常常被我们用于登录之后的数据获取,使我们不用再一次又一次的传递cookies。
首先我们需要去生成一个Session对象,然后用这个Session对象来发起访问,发起访问的方法与正常的请求是一模一样的。
import requests
session = requests.Session()
session.get('http://httpbin.org/cookies/set/sessioncookie/123456789')
resp = session.get('http://httpbin.org/cookies')
print(resp.text)
同时,需要注意的是,如果是我们在get()方法中传入headers和cookies等数据,那么这些数据只在当前这一次请求中有效。如果你想要让一个headers在Session的整个生命周期内都有效的话,需要用一下的方式来进行设置:
#设置整个headers
session.headers-{
'user-agent':'my-app/0.0.1'
}
#增加一条headers
session.headers.updata({'x-test':'true'})
下面是以12306登录页面进行session验证码的例程:
import requests,re,base64
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/76.0.3809.100 Safari/537.36'
}
def get_point_by_index(indexs):
"""
根据图片的序号,快速获取坐标
:param indexs: 1,2
:return: 111,111,222,222
"""
map = {
'1':'39,43',
'2':'109,43',
'3':'185,43',
'4':'253,43',
'5':'39,121',
'6':'109,121',
'7':'185,121',
'8':'253,121',
}
indexs = indexs.split(',')
temp = []
for index in indexs:
temp.append(map[index])
return ','.join(temp)
session = requests.Session()
session.headers.update(headers)
# 1.访问首页面 服务器给出cookie
# 2.验证用户名和密码 携带上一次的cookie
# 3.权限验证 携带上一次的cookie
# ↑↑↑↑ 一个会话session ↑↑↑↑
# 1.访问首页面
login_page_url ='https://kyfw.12306.cn/otn/resources/login.html'
response = session.get(login_page_url)
# print(response.cookies)#服务器给的cookies
# 2.下载 图片验证码 captcha ->Headers->General ->Request URL
captcha_url = 'https://kyfw.12306.cn/passport/captcha/captcha-image64?login_site=E&module=login&rand=sjrand&1572094182837&callback=jQuery19108983483408112036_1572093882677&_=1572093882678'
captcha_response = session.get(captcha_url)
# print(captcha_response.text)
# 获取图片信息
img_data = re.findall(b'image":"(.*?)"',captcha_response.content)[0]
# print(img_data)
with open('captcha.jpg','wb') as f:
f.write(base64.b64decode(img_data)) #解码后的图片
cookies = captcha_response.cookies
# 3.验证验证码
check_captcha_api = 'https://kyfw.12306.cn/passport/captcha/captcha-image64';
args={
'login_site': 'E',
'module': 'login',
'rand': 'sjrand',
'answer':get_point_by_index(input('please enter the right image coordinate:')),
'callback':'jQuery19106214710238514467_1572095054153',
'_':'1572095054154',#防止浏览器缓存
}
# print(args)
check_response=session.get(check_captcha_api,params=args)
print(check_response.text)