文章目录
第三章 requests库的使用
第二章记录了urllib的基本用法,获取网页数据。但是对于那些需要登录验证或者Cookies处理等其他的处理时,要用到Handler来处理。
urllib库中的urlopen()方法以GET方式请求网页的,对应到requests中就是requets.get(),其他请求方式同理。
3.1 基本用法
3.1.1 requests.get()
构建一个最简单的get请求:
import requests
url = 'http://httpbin.org/get'
data = {
'name': '铁锅遁大鹅',
'age': '20'
}
res = requests.get(url=url, params=data)
print(res.text)
print(res.json())
{
"args": {
"age": "20",
"name": "\u94c1\u9505\u9041\u5927\u9e45"
},
"headers": {
"Accept": "*/*",
"Accept-Encoding": "gzip, deflate",
"Host": "httpbin.org",
"User-Agent": "python-requests/2.27.1",
"X-Amzn-Trace-Id": "Root=1-6208edec-715b904420836ef97248fbf4"
},
"origin": "117.150.133.230",
"url": "http://httpbin.org/get?name=\u94c1\u9505\u9041\u5927\u9e45&age=20"
}
{'args': {'age': '20', 'name': '铁锅遁大鹅'}, 'headers': {'Accept': '*/*', 'Accept-Encoding': 'gzip, deflate', 'Host': 'httpbin.org', 'User-Agent': 'python-requests/2.27.1', 'X-Amzn-Trace-Id': 'Root=1-6208edec-715b904420836ef97248fbf4'}, 'origin': '117.150.133.230', 'url': 'http://httpbin.org/get?name=铁锅遁大鹅&age=20'}
- 返回结果中包含了请求头、url、ip信息。对于GET请求,如果想要添加别的信息,做法与第二章中请求对象的定制相似。把数据放在字典中传给params参数。
- 返回的是str类型,但是是json格式,可以用json()方法解析返回结果,将结果是json格式的字符串转化为字典。
- 传递请求头信息也与urllib.request类似,将头信息存在字典中放入requests.get()
3.1.2 requests.post()
post请求返回的结果中form部分就是提交的数据
import requests
data = {
'name': 'haha',
'age': 20
}
url = 'http://httpbin.org/post'
r = requests.post(url, data=data)
print(r.text)
{
"args": {},
"data": "",
"files": {},
"form": {
"age": "20",
"name": "haha"
},
"headers": {
"Accept": "*/*",
"Accept-Encoding": "gzip, deflate",
"Content-Length": "16",
"Content-Type": "application/x-www-form-urlencoded",
"Host": "httpbin.org",
"User-Agent": "python-requests/2.27.1",
"X-Amzn-Trace-Id": "Root=1-61faa48a-100ee1850c53815f54d1aec6"
},
"json": null,
"origin": "61.242.148.195",
"url": "http://httpbin.org/post"
}
3.1.3 响应
发送请求后,得到的就是响应。一般使用text和content获取了响应的内容,content获取的是bytes类型的数据,像获取图片就要是bytes类型。还有很多属性和方法获取其他信息,如状态码,响应头,Cookies等。
3.2 高级用法
如文件上传、Cookies设置、代理设置等。
3.2.1 文件上传
requests可以模拟提交数据,对于有的网站需要上传文件,可以用它来实现。注意的是待上传的文件要和当前脚本在同一目录下。在返回的响应中,上传的文件会在files字段中被标识出来。
import requests
url = 'http://httpbin.org/post'
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; rv:2.0.1) Gecko/20100101 Firefox/4.0.1'
}
files = {
'file': open('favicon.ico', 'rb')
}
r = requests.get(url=url, headers=headers, files=files)
print(r.text)
3.2.2 Cookies
第二章笔记简单记录了urllib库中Cookie处理,写法比较复杂,先声明一个CookieJar对象,然后利用HTTTPCookieProcess构建一个handler,然后用build_opener()构建出opener去执行open()。然而使用requests,获取和设置Cookie都相对简洁些。
- 直接调用Cookies属性得到Cookie,它是RequestsCookieJar类型,用items()方法转换成元组组成的列表。
import requests
r = requests.get('https://www.baidu.com')
print(r.cookies)
for key, value in r.cookies.items():
print(key+'='+value)
<RequestsCookieJar[<Cookie BDORZ=27315 for .baidu.com/>]>
BDORZ=27315
利用Cookie维持登录状态,
import requests
headers = {
'cookie': '_zap=baeed8ad-3c68-4715-90c3-390a4390a003;.................,
'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; rv:2.0.1) Gecko/20100101 Firefox/4.0.1',
'referer': 'https://www.zhihu.com/signin?next=%2F'
}
url = 'https://www.zhihu.com/'
r = requests.get(url=url, headers=headers)
print(r.text)
结果得到的是登录之后的源码。也可以通过cookies参数来设置,也就是不把cookies放在headers字典中,但是需要构造RequestsCookieJar对象,而且需要分割一下cookies。
3.2.3 会话维持
在requests中可以直接用get()或者post()等方法模拟请求,但每一次实际上相当于不同的会话,也就是说每发送请求一次就又打开一个浏览器。那么这种方式明显在某些场合使用不方便,例如:登录某个网站,查看个人信息啊,查看消息啊等。用上面的方法还要时时刻刻把cookie带着,虽然可行,但难免繁琐。
那么每次请求打开的是新的浏览器选项卡而不是新的浏览器,也就是维持同一个会话,后面的请求是不是就可以不用重复设置cookie了?
一个新的工具Session对象。
- 什么是Session:Session是另一种记录客户状态的机制,不同的是Cookie保存在客户端浏览器中,而Session保存在服务器上。客户端浏览器访问服务器的时候,服务器把客户端信息以某种形式记录在服务器上。这就是Session。客户端浏览器再次访问时只需要从该Session中查找该客户的状态就可以了
import requests
# 请求一个测试网址,请求时设置cookis叫number内容123。随后请求http://httpbin.org/cookies,获取当前cookies
requests.get('http://httpbin.org/cookies/set/number/123')
result = requests.get('http://httpbin.org/cookies')
print(result.text)
{
"cookies": {}
}
import requests
s = requests.Session()
s.get('http://httpbin.org/cookies/set/number/123')
r = s.get('http://httpbin.org/cookies')
print(r.text)
{
"cookies": {
"number": "123"
}
}
利用Session,可以做到模拟会话而不用担心Cookies问题,通常用于模拟登录成功之后再进行下一步的操作。
3.2.4 SSL证书验证
requests有检验ssl证书的功能。可以使用verify参数控制是否检查此证书,默认是True,会自动检验。
import requests
r = requests.get('https://www.dae.com')
print(r.status_code)
将verify参数改成False,但是会有警告。
3.2.5 代理设置
在第二章笔记中也简单记录了代理,对于某些网站如果大规模且频繁地爬取数据,网站可能会发现是在爬虫,会弹出验证码,登录认证等,甚至直接封禁客户端的ip。为了保护我们的ip,代理设置就体现其重要作用了。
在Urllib.request中代理设置还是老三样儿:
# 获取handler对象
proxy = {
'http': '39.155.253.58:8060'
}
handler = urllib.request.ProxyHandler(proxies=proxy)
# 获取opener对象
opener = urllib.request.build_opener(handler)
# 调用open方法
response = opener.open(request)
在requests中:
import requests
proxies = {
'http': '111.59.199.58:8118',
'https': '111.59.199.58:8118'
}
r = requests.get('https://www.taobao.com', proxies=proxies)
用Python爬虫抓取免费代理IP_Python中文社区-CSDN博客
3.2.6 Prepared Request
在Urllib中我们可以将请求表示为数据结构,其中各个参数可以用request对象来表示。在requests中这种数据结构就叫Prepared Request。
我们使用requests库的get和post方法可以直接发送请求,比Urllib中快,那么这个请求在requests内部如何实现的呢?
requests在发送请求之前在内部构造了一个Request对象
这个Request对象里面包含各种参数:url、headers、data...
发送这个Request对象,请求成功后得到响应,也就会得到Response对象,再解析它就欧了
这里我们引入了 Request,构造了一个 Request 对象,再调用 Session 的 prepare_request 方法将其转换为一个 Prepared Request 对象,然后调用 send 方法发送
from requests import Request, Session
url = 'http://httpbin.org/post'
data = {
'name': 'goose'
}
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; rv:2.0.1) Gecko/20100101 Firefox/4.0.1'
}
s = Session()
req = Request('post', url=url, data=data, headers=headers)
prepped = s.prepare_request(req)
r = s.send(prepped)
print(r.text)
这样同样达到了post请求的结果,利用Request对象可以将请求当作一个独立对象,更加灵活的实现请求。