概述
requests
内容:
- requests模块的认识
- requests发送get请求
- requests获取响应数据
- requests发送带headers的请求
- requests发送带参数的请求
- requests发送POST请求
- requests使用代理
- requests处理cookie
- js的逆向解析
- urllib基本介绍
为什么要重点学习requests模块,而不是urllib
- 企业中用的最多的就是requests
- requests的底层实现就是urlllib
- requests在python2和python3中通用。方法完全一样
- requests简单易用
- requests能够自动帮助我们解压(gzip压缩的等)响应内容
requests作用:
作用:发送网络请求,返回响应数据
requests模块发送简单的get请求、获取响应
import requests
#目标url
url='https://www.baidu.com'
#向目标url发送get请求
response=requests.get(url)
#打印响应内容
print(response.text)
response的常用属性:
response.text | 响应体 str类型 |
---|---|
response.content | 响应体bytes类型 |
response.status_code | 响应状态码 |
response.request.headers | 响应对应的请求头 |
response.request.cookies | 响应对应请求的cookie |
response.cookies | 响应的cookie (经历了set-cookie动作) |
思考 : text是reposponse的属性还是方法呢?
一般来说名词,往往都是对象的属性,对应的动词是对象的方法
response.text和response.content的区别
-
response.text
- 类型:str
- 解码类型:requests模块自动根据HTTP头部对响应的编码做出有根据的推测,推测的文本编码。
- 如何修改编码方式:requests.encoding='gbk’
-
response.content
- 类型:bytes
- 解码类型:没有指定
- 如何修改编码方式:requests.content.decode(‘utf8’)
获取网页源码的通用方式:
response.content.decode()
response.content.decode("GBK")
response.text
以上三种方法从前往后尝试,能够100%解决所有网页编码的问题
更推荐使用response.content.decode()的方式获取响应的html页面
练习:把网络上的图片保存到本地
图片的url:https://www.baidu.com/img/bd_logo1.png**
利用requests模块发送请求获取响应
**以2进制写入的方式打开文件,并将response响应的二进制内容写入
import requests
response=requests.get(url='https://www.baidu.com/img/bd_logo1.png')
#响应本身就是一个图片,并且是二进制类型
#以二进制+写入的方式打开文件
with open('baidu.png','wb') as f:
#写入response.content bytes二进制类型
f.write(response.content)
import request
response=requests.get(url='https://www.baidu.com')
print(response.requests.headers) #打印响应对应请求的请求头信息
header的形式:字典
为什么请求需要带上header ?
模拟浏览器,欺骗服务器,获取和浏览器一致的内容
- 用法:
requests.get(url,headers=headers)
- 完整的代码
import requests
url='https://www.baidu.com'
headers={"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.99 Safari/537.36"}
#在请求头中带上User-Agent,模拟浏览器来发送请求
response=requests.get(url,headers=headers)
#打印请求头信息
print(response.request.headers)
- 发送带参数的请求**
**我们在使用百度搜索的时候经常发现url地址中会有一个?,那么该问号后边的就是请求参数,又叫做查询字符串
什么叫做请求参数
-
例1:http://www.webkaka.com/tutorial/server
-
例2:https://www.baidu.com/s?wd=python&a=c
-
请求参数的形式:字典
- kw:{‘wd’:‘长城’}
-
请求参数的用法:
requests.get(url,params=kw)
-
关于参数的注意点:**
**在url地址中,很多参数是没有用的,比如百度搜索的url地址,期中参数只有一个字段有用,其他的都可以删除,如何确定哪些请求参数有用或者没用:挨个尝试!对应的,在后续的爬虫中,越到很多参数的url地址,都可以尝试删除参数 -
两种方式:发送带参数的请求**
**对https://www.baidu.com/s?wd=python发起请求可以使用requests.get(url,params=kw)的方式-
#方式一:利用params参数发送带参数的请求
import requests url='https://www.baidu.com/s?' kw={'wd':'python'} response=requests.get(url,headers=headers,params=kw)
- #当有多个请求参数时,requests接收的params参数为多个键值对的字典,比如
"?wd=python&a=c" 相当于{'wd':'python','a':'c'}
-
也可以直接对https://www.baidu.com完整的url直接发送请求,不适用params参数
import requests url='https://www.baidu.com/s?wd=python' response=requests.get(url,headers=headers)
requests.post
哪些地方我们会用到POST请求?
- 登录注册(POST比GET更安全)
- 需要传输大文本内容的时候(POST请求对数据长度没有要求)
- 所以同样的,我们的爬虫也需要在这两个地方回去模拟浏览器发送post请求
requests发送post请求语法:
- 用法:
response=requests.post('http://www.baidu.com/',data=data,headers=headers)
- data的形式:字典
POST请求练习
下面我们通过金山翻译的例子看看post请求如何使用**
**地址;**http://fy.iciba.com/
1、思路分析
**抓包确定请求的url地址
2、确定请求的参数
3、确定返回数据的位置
4、模拟浏览器获取数据JSON函数
使用JSON函数需要导入json库:
import json
json.dumps ** 将python对象编码成JSON字符串** json.loads ** 将已编码的JSON字符串解码为python对象** 金山词霸例子:
import requests url='http://fy.iciba.com/ajax.php?a=fy' response=requests.post(url=url,data={'w':'good'}) if response.status_code==200: print(response.json())
小结:**
**在模拟登录等场景,经常需要发送post请求,直接使用requests.post(url,data)即可 -
代理
为什么要使用代理:
- 让服务器以为不是同一个客户端在请求
- 防止我们的真实地址被泄露,防止被追究
理解使用代理的过程
• —request——> ——requests——>
浏览器 代理 Web server
• <——response—— <——response——
理解正向代理和反向代理的区别
浏览器————>服务器
反向代理:
浏览器————>nginx————>服务器
正向代理:
浏览器————>代理————>google服务器
通过上图可以看出:
正向代理:对于浏览器知道服务器的真实地址,例如VPN**
**反向代理:浏览器不知道服务器的真实地址,例如nginx
用法:
requests.get('http://www.baidu.com',proxies=proxies)
proxies的形式:字典
例如:
proxies={'http':'http://12.34.56.79:9527','https':'https://12.34.56.79:9527'}
代理IP的分类
根据代理ip的匿名程度,代理IP可以分为下面几类:
- 透明代理:透明代理虽然可以直接“隐藏”你的IP地址,但是还是可以查到你是谁
- 匿名代理:使用匿名代理,别人只能知道你用了代理,无法知道你是谁
- 高匿代理:高匿代理让别人根本无法发现你是在用代理,所以是最好的选择
在使用的时候,使用高匿代理效果最好
从请求使用的协议可以分为:
- http代理
- https代理
- socket代理等
- 不同分类的代理,在使用的时候需要根据抓取网站的协议来选择
代理IP是非常必要的一种反反爬的方式
但是即使使用了代理ip,对方服务器仍然会有很多的方式来检测我们是否是一个爬虫,比如:
- 一段时间内,检测ip访问的频率,访问太多频繁会屏蔽
- 检测Cookie,User-Agent,Referer等header参数,若没有则屏蔽
- 服务方购买所有代理提供商,加入到反爬虫数据库里,若检测是代理则屏蔽
- 所以更好的方式在使用代理Ip的时候使用随机的方式进行选择使用,不要每次都用一个代理ip
代理ip池的更新
购买的代理ip很多时候大部分(超过60%)可能都没办法使用,这个时候就需要通过程序去检测哪些可用,把不能用的删除掉。
小结:
- requests发送post请求使用requests.post方法,带上请求体,其中请求体需要是字典的形式,传递给data参数接收
- 在requests中使用代理,需要准备字典形式的代理,传递给proxies参数接收
- 不同协议的url地址,需要使用不同的代理去请求
cookie
cookie的工作原理是:
- 由服务器产生内容,浏览器收到请求后保存在本地;当浏览器再次访问时,浏览器会自动带上cookie,这样服务器就能通过cookie的内容来判断这个是‘谁’了。
- cookie虽然在一定程度上解决了‘保持状态’的需求,但是由于cookie本身最大支持4096字节,以及cookie本身保存在客户端,可能被拦截或窃取,因此就需要有一种新的东西,他能支持更多的字节,并且他保存在服务器,有较高的安全性。这就是session
cookie存储到客户端
- 优点:数据存储在客户端。减轻服务端的压力,提高网站的性能
- 缺点:安全性不高,在客户端很容易被查看或破解用户会话信息
- 当客户端浏览器第一次请求服务器时,服务器会再response中设置一个Set-Cookies的字段,用来标记用户的身份,客户端浏览器会把cookies放在请求头中一起提交给服务器,服务器检查该Cookies即可找到对应的会话是什么,再通过判断会话来辨认用户的状态。
- 当我们成功登录网站时,网站会告诉客户端应该设置哪些Cookies信息,以保持登录状态。如果客户端浏览器传给服务器的cookies无效或者会话过期,可能就会收到错误的响应或者跳转到登录页面重新登陆
requests模块处理cookie相关的请求
爬虫中使用cookie
为了能够通过爬虫获取到登陆后的页面,或者是解决通过cookie的反扒,需要使用reques来处理cookie相关的请求
爬虫中使用cookie的利弊
-
带上cookie的好处
- 能够访问登陆后的页面
- 能够实现部分反反爬
-
带上cookie的坏处
- 一套cookie往往对应的时一个用户的信息,请求太频繁有更大的可能性被对方识别为爬虫
- 那么上面的问题如何解决? 使用多个账号
requests处理cookie有三种方法:
- cookie字符串放在headers中
- cookie字典放传给请求方法的cookies参数接收
- 使用requests提供的session模块
注意:
cookie有过期时间,所以直接复制浏览器中的cookie可能意味着下一程序继续运行的时候需要替换代码中的cookie,对应的我们也可以通过一个程序专门来获取cookie供其他程序使用;当然也有很多网站的cookie过期时间很长,这种情况下,直接复制cookie来使用更加简单
使用cookies参数接收字典形式的cookie
- cookies的形式:字典
- cookies={‘cookie的name’:‘cookie的value’}
- 使用方法:
requests.get(url,headerss=headers,cookies=cookie_dict}
使用requests.session处理cookie
前面使用手动的方式使用cookie,那么有没有更好的方法在requests中处理cookie呢?
requests提供了一个叫做session类,来实现客户端和服务端的会话保持
会话保持有两个内涵:
- 保存cookie,下一次请求会带上前一次的cookie
- 实现和服务端的长连接,加快请求速度
使用方法
session=requests.session()
response=session.get(url,headers)
session实例在请求了一个网站后,对方服务器设置在本地的cookie会保存在session中,下一次再使用session请求对方服务器的时候,会带上前一次的cookie
小结:
- cookie字符串可以放在headers字典中,键为Cookie,值为cookie字符串
- 可以把cookie字符串转化为字典,使用请求方法的cookies参数接收
- 使用requests提供的session模块,能够自动实现cookie的处理,包括请求的时候携带cookie,获取响应的时候保存cookie
requests中的cookirJar的处理方法
requests处理证书错误
使用requests获取的response对象,具有cookies属性,能够获取对方服务器设置在本地的cookie,但是如何使用这些cookie呢?
方法介绍:
response.cookies时CookieJar类型**
**使用requests.utils.dict_from_cookiejar,能够实现吧cookiejar对象转化为字典
返回证书、超时处理
为了在代码中能够正常的请求,我们修改添加一个参数verify
import requests
url='https://www.12306.cn/mormhweb/'
response=requests.get(url,verify=Fasle)
超时参数使用方法如下:
response=requests.get(url,timeout=3)
通过添加timeout参数,能够保证在3秒钟内返回响应,否则会报错
注意:
-
这个方法还能够拿来检测代理ip的质量,如果一个代理ip在很长时间没有响应,那么添加超时之后也会报错,对应的这个ip就可以从代理ip池中删除
-
使用超时参数能够加快我们整体的请求速度,但是在正常的网页浏览过成功,如果发生速度很慢的情况,我们会做的选择是刷新页面,那么在代码中,我们是否也可以刷新请求呢?
- 对应的,retrying模块就可以帮助我们解决
使用retrying模块提供的retry模块
通过装饰器的方式使用,让被装饰的函数反复执行**
**retry中可以传入参数stop_max_attemp_number,让函数报错后继续重新执行,达到最大执行次数的上限,如果每次都报错,整个函数报错,如果中间有一个成功,程序继续往后执行
retrying和requests的简单封装
实现一个发送请求的函数,每次爬虫中直接调用该函数即可实现发送请求,在其中
- 使用timeout实现超时报错
- 使用retrying模块实现重试
代码参考:
import requests
from retrying import retry
#最大重试3次,3次全部报错,才会报错
@retry(stop_max_attempt_number=3)
def _parse_url(url):
#超时的时候会报错并重试
response=requests.get(url,headers=headers,timeout=3)
#状态码不是200,也会报错并重试
assert response.status_code==200
return response
def parse_url(url):
try:#进行异常捕获
response=_parse_url(url)
except Exception as e:
print(e)
#报错返回None
response=None
return response
小结
- requests.utils.dict_from_cookiejar能够实现cookiejar转化为字典
- 请求方法中添加verify=False能够实现请求过程中不验证证书
- 请求方法中添加timeout能够实现强制程序返回结果,否则会报错
- retrying模块能够实现捕获函数的异常,反复执行函数的效果,和timeout配合使用,能够解决网络波动带来的请求不成功的问题
@retry(stop_max_attempt_number=3)
def getHTML(url):
在函数内出错误后才执行第二次、第三次 如果函数内没有错误 就只执行一次 报错后后面的代码不执行
最后
以上就是勤恳饼干为你收集整理的requests使用(get/post/代理/cookie/session/cookirJar/证书/超时处理)的全部内容,希望文章能够帮你解决requests使用(get/post/代理/cookie/session/cookirJar/证书/超时处理)所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复