python3之requests
1、requests简介
requests是通过urllib3实现自动发送HTTP/1.1请求,它能轻松的实现cookies,登陆验证,代理设置等操作。
Python内置的urllib模块,用于访问网络资源。但是,它用起来比较麻烦,而且,缺少很多实用的高级功能。
更好的方案是使用requests。它是一个Python第三方库,处理URL 资源特别方便
requests实现内容:
- 保持活力和连接池
- 支持国际域名和网址
- 会话与Cookie持久性
- 浏览器式SSL验证
- 自动内容解码
- 基本/摘要式身份验证
- 自动解压缩
- Unicode响应body
- HTTP(s)代理支持
- 多部分文件上传
- 流媒体下载
- 连接超时
- 分块的请求
- .netrc 支持
2、requests的安装
(1)源码安装:
- git clone git: // github.com / requests / requests.git # 克隆公共存储库
- 或者下载tarball
- curl - OL https: // github.com / requests / requests / tarball / master
- cd requests / requests
- pip install .
(2)pip安装
- pip install requests
(3)pipenv安装在虚拟环境下安装
- pipenv install requests
request依赖包关系:
- requests==2.19.1
- - certifi [required: >=2017.4.17, installed: 2018.4.16] #CA认证模块
- - chardet [required: <3.1.0,>=3.0.2, installed: 3.0.4] #通用字符编码检测器模块
- - idna [required: <2.8,>=2.5, installed: 2.7] #国际化域名解析模块
- - urllib3 [required: <1.24,>=1.21.1, installed: 1.23] #线程安全HTTP库
3、requests请求
所有请求的功能可通过这7种方法访问,他们都返回response对象的一个实例。
(1)requests.request(method,url,**kwargs):构造并发送一个request,返回一个response对象
参数:
- method: request对象的方法(POST)
- url: request对象的URL
- params:可选的,要在查询字符串中发送的字典或字节request
- data:可选的,字典或元祖列表以表单编码,字节或类似文件的对象在主体中发送[(key,value)]
- json:可选的,一个json可序列化的python对象,在主体中发送request
- headers:可选的,用于编写http头信息
- cookies:可选,用dict或cookieJar对象发送Cookies
- file:可选,用于多部分编码上传的字典,可以是多元祖,其中是定义给定文件的内容类型的字符串,以及包含问文件添加的额外头文件的类字典对象
- auth:可选,身份验证元祖,自定义http身份验证
- timeout:可选,发送等待请求数据的超时时间(float/tuple),设置为元祖即为练级connect和read读取超时,如果设置为None即为永久等待
- allow_redirects:布尔值,可选,启用或禁用GET,OPTIONS,POST,PUT,PATCH,DELETE,HEAD重定向,默认为true
- proxies:可选,字典映射协议到代理的URL
- verify:可选,可以是布尔值,可以指定验证服务器的TLS证书路径,默认为true
- stream:可选,如果是False,响应内容将立即下载
- cert:可选,如果是string,则为ssl客户端证书文件路径,如果是元祖则('cert','key')指定证书和密钥
- #!/usr/bin/env python
- # -*- coding: utf-8 -*-
- # @Time : 2018/6/20 10:04
- # @Author : Py.qi
- # @File : req_reqst.py
- # @Software: PyCharm
- from requests import request
- header={
- 'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.79 Safari/537.36'
- }
- response=request('GET','https://api.github.com/events',headers=header) #定义头信息发送请求返回response对象
- print(response.url) #返回请求的URL
- print(response.status_code) #返回状态码200
- print(response.encoding) #返回编码
- print(response.text) #返回响应的内容以unicode表示
- print(response.headers) #返回头信息
- print(response.cookies) #返回cookies CookieJar
- print(response.json()) #返回json数据
(2)requests.head(url,**kwargs):发送head请求,url:网站URL地址,返回一个response对象
- #!/usr/bin/env python
- # -*- coding: utf-8 -*-
- # @Time : 2018/6/20 11:19
- # @Author : Py.qi
- # @File : req_head.py
- # @Software: PyCharm
- from requests import head
- header=head('https://github.com/get')
- print('text:',header.text) #不会返回内容信息
- print('headers:',header.headers) #返回头信息
- print(header.cookies.items()) #返回cookies元组列表
(3)requests.get(url,params=None,**kwargs):发送GET请求,params:要在查询字符串中发送的字典或字节request,返回一个response对象
- #!/usr/bin/env python
- # -*- coding: utf-8 -*-
- # @Time : 2018/6/20 11:29
- # @Author : Py.qi
- # @File : req_get.py
- # @Software: PyCharm
- from requests import get
- response=get('http://httpbin.org/get',params={'name':'py.qi','age':22})#添加参数查询
- print(response.text) #返回结果包含args参数,headers头信息,URL和IP信息
- print(response.url) #返回组合的URL(http://httpbin.org/get?name=py.qi&age=22)
- print(response.json()) #如果返回网页是JSON格式,可以使用json()方法解析返回字典数据
抓取网页:
- #!/usr/bin/env python
- # -*- coding: utf-8 -*-
- # @Time : 2018/6/20 11:46
- # @Author : Py.qi
- # @File : req_zhuaqu.py
- # @Software: PyCharm
- import requests
- import re
- url='http://www.runoob.com/python3/python3-reg-expressions.html'
- headers={
- 'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.79 Safari/537.36'
- }
- response=requests.get(url,headers=headers)
- response.encoding='UTF-8'
- #print(response.encoding)
- #print(response.text)
- pattern = re.compile('id="content">.*?<h1>(.*?)</h1>.*?<p>(.*?)</p><p>(.*?)</p>.*?<p>(.*?)</p>.*?<p>(.*?)</p>.*?<p>(.*?)</p>',re.S)
- text = re.search(pattern,response.text)
- for i in text.groups():
- print(i)
- #
- Python3 正则表达式
- 正则表达式是一个特殊的字符序列,它能帮助你方便的检查一个字符串是否与某种模式匹配。
- Python 自1.5版本起增加了re 模块,它提供 Perl 风格的正则表达式模式。
- re 模块使 Python 语言拥有全部的正则表达式功能。
- compile 函数根据一个模式字符串和可选的标志参数生成一个正则表达式对象。该对象拥有一系列方法用于正则表达式匹配和替换。
- re 模块也提供了与这些方法功能完全一致的函数,这些函数使用一个模式字符串做为它们的第一个参数。
抓取二进制文件:图像,BytesIO创建内存对象存储数据,Image打开图像获得图像对象,也可以用上下问方式将图像直接写入文件,适合音频,视频等文件
- #!/usr/bin/env python
- # -*- coding: utf-8 -*-
- # @Time : 2018/6/20 14:10
- # @Author : Py.qi
- # @File : req_content.py
- # @Software: PyCharm
- import requests
- from io import BytesIO
- from PIL import Image
- url='http://docs.python-requests.org/en/master/_static/requests-sidebar.png'
- r=requests.get(url)
- i=Image.open(BytesIO(r.content)) #获得一个图像对象
- print(i.format,i.size,i.mode) #查看图像的来源,像素和像素类型(RGB)
- #print(i.show()) #显示图片
- i.save('requests_log.png') #保存图像数据到文件
(4)requests.post(url,data=None,json=None,**kwargs):发送POST请求,data:字典数据也可以是元组列表,将被表单编码,以字节或文件对象在数据主体中发送
json:在json数据中发送正文,返回一个response对象
- #!/usr/bin/env python
- # -*- coding: utf-8 -*-
- # @Time : 2018/6/20 14:41
- # @Author : Py.qi
- # @File : req_post1.py
- # @Software: PyCharm
- import requests
- data={'k1':'v1','k2':'v2'}
- r = requests.post('http://httpbin.org/post',data=data) #以表单数据发送数据
- body=r.json() #获得字典格式的返回数据
- print(body['form']) #窃取表单编码数据
上传文件:files参数指定上传文件,上传的文件在主体数据中
- #!/usr/bin/env python
- # -*- coding: utf-8 -*-
- # @Time : 2018/6/20 15:23
- # @Author : Py.qi
- # @File : req_post_file.py
- # @Software: PyCharm
- import requests
- url='http://httpbin.org/post'
- files={'file':open('network.csv','rb')}
- files1={'file':('filename.xls',open('fileanme.xls','rb'),'application/vnd.ms-excel',{'expires':''})} #设置文件名
- r=requests.post(url,files=files) #指定文件发送请求
- print(r.json()['files'])
多个文件上传:
- import requests
- url='http://httpbin.org/post'
- multple_files=[
- ('images1',('11.jpg',open('11.jpg','rb'),'image/jpg')),
- ('images2',('22.jpg',open('22.jpg','rb'),'image/jpg')),
- ] #字段代表意思依次为:文件名,文件对象,文件类型
- r=requests.post(url,files=multple_files)
- print(r.text)
在网站中PUT,PATCH,DELETE请求很少使用,不做介绍
(5)requests.put(url,data=None,**kwargs):发送PUT请求参数同POST一样,将返回一个response对象
(6)requests.patch(url,data=None,**kwargs):发送PATCH请求
(7)requests.delete(url,**kwargs):发送DELETE请求
4、请求响应
class response.Response :该Response对象包含服务器对HTTP请求的响应信息
该对象包含的属性和方法:
apparent_encodind:
由chardet库提供的明显编码。
close():
将连接释放回池中,即关闭连接,通常不需要调用
content:
响应的内容,以字节为单位。
cookies
=None :服务器发回的Cookies CookieJar。
elapsed
=None :发送请求和响应到达之间所经过的时间量(作为timedelta)。该属性具体测量发送请求的第一个字节和完成解析报头之间的时间。因此,它不受消费响应内容或stream
关键字参数值的影响。
encoding
=None :编码以在访问r.text时进行解码。
headers
=None :不区分大小写的响应头字典。例如,headers['content-encoding']
将返回'Content-Encoding'
响应头的值。
history
=None :Response
请求历史记录中的对象列表。任何重定向响应都会在这里结束。该列表从最旧的到最近的请求进行排序。
is_permanent_redirect:
如果此响应为真,则为重定向的永久版本之一。
is_redirect:
如果此响应是可以自动处理的格式良好的HTTP重定向,则为真。
iter_content
(chunk_size = 1,decode_unicode = False ):迭代响应数据。在请求中设置stream = True时,可以避免将内容一次性读入内存以获得较大的响应。块大小是它应该读入内存的字节数;chunk_size必须是int或None类型。stream = True将在数据以任何大小接收到的数据到达时读取数据。如果stream = False,则数据作为单个块返回;如果decode_unicode为True,则内容将使用基于响应的最佳可用编码进行解码。
iter_lines(
chunk_size = 512,decode_unicode = None,delimiter = None ):迭代响应数据,一次一行。在请求中设置stream = True时,可以避免将内容一次性读入内存以获得较大的响应。
json
(** kwargs ):返回响应的json编码内容
links:
返回解析的响应头部链接
next:
返回重定向链中下一个请求的PreparedRequest
ok:
如果status_code
小于400 则返回True,否则返回False
reason
=None:响应HTTP状态的文本原因,例如“未找到”或“确定”。
request
=None:一个响应的对象。
status_code
=None:整数响应HTTP状态的代码,例如404或200。
text:
响应的内容,以unicode表示。
url
=None:响应的最终URL位置
- 发送请求后,会得到响应信息,我们可以使用text和content获取相应的内容,此外还有很多属性和方法来获取其他信息,如状态码,响应头,Cookies等
- #!/usr/bin/env python
- # -*- coding: utf-8 -*-
- # @Time : 2018/6/20 15:51
- # @Author : Py.qi
- # @File : req_respon.py
- # @Software: PyCharm
- import requests
- headers={'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.79 Safari/537.36'}
- r=requests.get('http://docs.python-requests.org/en/master/',headers=headers)
- print('chardet提供的编码:',r.apparent_encoding)
- print('响应字节内容:',r.content)
- print('响应cookies:',r.cookies.items())
- print('请求到响应之间的时间:',r.elapsed)
- print('响应编码:',r.encoding)
- print('响应头信息:',r.headers)
- print('头信息中的server:',r.headers['Server'])
- print('请求历史记录:',r.history)
- print('迭代响应数据:',r.iter_lines())
- #print('响应json编码数据:',r.json())
- print('返回解析的响应头链接:',r.links)
- print('返回状态码:',r.status_code)
- print('响应str内容:',r.text)
- print('响应URL:',r.url)
- print('返回发送的头参数:',r.request.headers)
- #
- chardet提供的编码: Windows-1254
- 响应字节内容: b'\n<!DOCTYPE html PUBLIC...
- 响应cookies: []
- 请求到响应之间的时间: 0:00:00.844991
- 响应编码: ISO-8859-1
- 响应头信息: {'Server': 'nginx/1.10.3 (Ubuntu)', 'Date': 'Wed, 20 Jun 2018 08:10:26 GMT', 'Content-Type': 'text/html', 'Last-Modified': 'Thu, 14 Jun 2018 13:27:43 GMT', 'Transfer-Encoding': 'chunked', 'Connection': 'keep-alive', 'Vary': 'Accept-Encoding', 'ETag': 'W/"5b226d4f-8438"', 'X-Cname-TryFiles': 'True', 'X-Served': 'Nginx', 'X-Deity': 'web05', 'Content-Encoding': 'gzip'}
- 头信息中的server: nginx/1.10.3 (Ubuntu)
- 请求历史记录: []
- 迭代响应数据: <generator object Response.iter_lines at 0x0000005A4A6F3888>
- 返回解析的响应头链接: {}
- 返回状态码: 200
- 响应str内容: <!DOCTYPE html PUBLIC.....
- 响应URL: http://docs.python-requests.org/en/master/
- 返回发送的头参数: {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.79 Safari/537.36', 'Accept-Encoding': 'gzip, deflate', 'Accept': '*/*', 'Connection': 'keep-alive'}
5、requests异常处理
exception requests.RequestException(*args, **kwargs):发送一个模糊的异常
exception requests.ConnectionError(*args, **kwargs):发生连接错误时的异常
exception requests.HTTPError(*args, **kwargs):发生HTTP错误时的异常
exception requests.URLRequired(*args, **kwargs):URL错误时的异常
exception requests.TooManyRedirects(*args, **kwargs):太多的重定向
exception requests.ConnectTimeout(*args, **kwargs):连接服务器是请求超时
exception requests.ReadTimeout(*args, **kwargs):服务器没有在指定的时间内发送数据
exception requests.Timeout(*args, **kwargs):请求超时
6、cookies
cookies包括下面四个类:
requests.utils.dict_from_cookiejar(cj):从CookieJar中返回一个键/值字典,cj为CookieJar对象,返回字典
requests.utils.add_dict_to_cookiejar(cj, cookie_dict):从键/值字典中返回CookieJar,cj指定CookieJar类型,cookie_dict,字典类型的JAR值,返回CookieJar
requests.cookies.cookiejar_from_dict(cookie_dict, cookiejar=None, overwrite=True):从键/值字典中返回CookieJar
class requests.cookies.RequestsCookieJar(policy=None):创建CookieJar,应用请求和未指定的请求和会话
cookieJar对象方法与属性:
- add_cookie_header(request):添加正确的Cookie到请求头
- clear(domain=None,path=None,name=None):清除cookies
- clear_expired_cookies():丢弃所有过期的cookies。
- clear_session_cookies():丢弃所有会话cookie。
- copy():返回这个RequestsCookieJar的副本。
- extract_cookies(response,request):根据请求提取允许的响应中的cookie。
- get(name,default = None,domain = None,path = None):类似于字典的get(),它还支持可选的域和路径参数,以解决在多个域中使用一个cookie jar造成的命名冲突。
- get_dict(domain=None,path=None):以可选域和路径作为参数,并返回符合要求的名称 - 值对Cookie的普通旧Python字典。
- items():类似Dict的项目()从jar中返回名称值元组的列表。
- iteritems():类似于dict的iteritems()从jar中返回名称值元组的迭代器。
- iterkeys():返回jar中cookie的名字的迭代器。
- itervalues():返回jar中cookie值的迭代器。
- keys():返回jar中的cookies的名字列表。
- list_domains():实用程序方法列出jar中的所有域。
- list_paths():实用程序方法列出jar中的所有路径。
- make_cookies(response,request):从响应对象中提取的Cookie对象的返回序列。
- multiple_domains():如果jar中有多个域,则返回True。否则返回False。
- pop(k[,d]) :移除指定的键并返回相应的值。
- popitem() :移除并返回(键,值)对
- set(name,value):还支持可选的域和路径参数,以解决在多个域中使用一个cookie jar造成的命名冲突。
- set_cookie(cookie,* args,** kwargs):设置一个cookie,不检查是否应该设置。
- set_cookie_if_ok(cookie,request):判断设置cookies是否可行,返回OK
- update(other):用另一个CookieJar或类似字典的cookie更新这个jar
- values():返回jar中cookie的值列表。
获取网站cookies:
- import requests
- r=requests.get('https://www.baidu.com')
- print(r.cookies)
- print(r.cookies.items())
- #
- <RequestsCookieJar[<Cookie BDORZ=27315 for .baidu.com/>]> #RequestsCookieJar对象
- [('BDORZ', '')]
使用cookies维持登陆状态:
- import requests
- headers={
- 'Cookie':'www51cto=F7A5DB397E1897B2B12EEC15A74FB351kYaA; Cto_lvt_=1503809599; ......#登陆网站后将cookie信息拷贝到此处
- 'User-Agent':'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.87 Safari/537.36'
- }
- r=requests.get('http://blog.51cto.com/zhangxinqi',headers=headers)
- print(r.text)
- print(r.cookies.items())
- #显示结果是登陆后的信息,表明登陆成功
- <!DOCTYPE html>
- <html lang="zh-CN">
- <head>
- <meta charset="UTF-8">
- <meta http-equiv="X-UA-Compatible" content="IE=edge">
- <meta name="viewport" content="width=device-width, initial-scale=1">
- <link type="favicon" rel="shortcut icon" href="/favicon.ico" />
- <title>80后小菜鸟-51CTO博客</title>
- <meta name="keywords" content="80后小菜鸟,linux技术,windows技术,网络技术,zabbix监控,数据库,虚拟化,自动化运维,系统安全,集群架构,python,企业应用,51CTO博客">
- [('_identity', '574c0a6fbf29ac6f44f66068e5f02b0b438aed6840bf......')]
创建RequestsCookieJar对象,使用cookies保持登陆:
- import requests
- from requests.cookies import RequestsCookieJar
- cookie='www51cto=F7A5DB397E1897B2B12EEC15A74FB351kYaA; ......'
- headers = { 'User-Agent':'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.87 Safari/537.36'
- }
- jar=RequestsCookieJar() #创建Jar对象
- for i in cookie.split(';'):
- key,value = i.split('=',1)
- jar.set(key,value) #设置cookies的键值
- #print(jar.items())
- r=requests.get('http://blog.51cto.com/zhangxinqi',cookies=jar,headers=headers) #传入cookies
- #print(r.text)
- print(r.headers['Set-Cookie'])
- print(r.request.headers['Cookie']) #获取客户端设置的cookie
7、请求会话(Session)
在requests中,如果直接利用get()和post()方法的确可以做到模拟网页的请求,但这实际上是相当于不同的会话,也就是说相当于使用了两个浏览器打开ileal不同的页面
如果利用psot()请求登陆了网站,然后使用get()方法请求个人信息,将得到两个完全不同的会话,就不能获取到个人信息,实际上可以使用设置cookies一样请求会话得到个人信息,
单方法显得很繁琐,可用使用更简单的方法,Session维持会话,利用它不需要设置cookies,它能帮助我们自动处理,下面先看下Session对象的API
class requests.Session:请求会话,提供cookie持久性,连接池和配置
方法与属性:
- auth=None 身份验证元祖
- cert=None SSL客户端证书路径,如果为元祖('cert','key')
- close() 关闭会话
- cookies=None 会话中设置的未处理的cookie的cookieJar,默认是一个RequestsCookieJar
- delete(url,**kwargs) 发送DELETE请求,返回一个response对象
- get(url) 发送GET请求,返回response对象
- get_adapter(url) 为给定的URL返回适当的连接适配器
- get_redirect_target(resp) 返回重定向URL或None
- head(url) 发送head请求,返回response对象
- headers=None 一个不区分大小写的字典,由字典发送Session
- hooks=None 事件处理
- max_redirects=None 允许最大重定向次数默认为30
- merge_environment_settings(url,proxies,stream,verify,cert) 检查环境并将参数设置合并,返回字典
- params=None 设置传递的参数
- post(url,data=None,json=None) 发送POST请求返回response对象
- prepare_request(request) 构造一个PreparedRequest并返回它,将生成一个请求的数据结构,通过Session发送
- proxies=None 代理URL
- request(method,url,params=None,data=None,headers=None,cookies=None,files=None,auth=None,timeout=None,allow_redirects=True,proxies=None,hooks=None,stream=None,verify=None,cert=None,json=None) 构建一个request,返回response对象
- send(request) 发送给定的PreparedRequest,返回Response对象
- stream=None 流响应的内容
- trust_env=None 代理设置的身份验证和信任环境设置
- verify=None SSL验证,设置为false则忽略SSL验证
测试能否获取自己设置的cookies:
- import requests
- #使用测试网站设置cookies的名称为number值为123456
- requests.get('http://httpbin.org/cookies/set/number/123456')
- r=requests.get('http://httpbin.org/cookies')
- print(r.text) #然后通过请求获取cookies,结果cookies显示为空
- #
- {"cookies":{}}
然而并不能获取到设置的cookies,说明它们使用不同的浏览器访问了页面,即得到的cookies会不一样
现在我们使用Seesion会话保持来设置请求看有什么变化
- import requests
- s=requests.Session() #创建session对象
- s.get('http://httpbin.org/cookies/set/number/123456')
- r=s.get('http://httpbin.org/cookies') #通过session获取请求的cookies
- print(r.text)
- #成功返回cookies信息
- {"cookies":{"number":""}}
利用session可以 做到模拟同一个会话而不用担心cookies的问题,它常用于模拟登陆成功后再进行下一步操作,可以模拟在同一个浏览器中打开同一个站点的不同页面
实例:通过session会话登陆页面获取个人信息
- #!/usr/bin/env python
- # -*- coding: utf-8 -*-
- # @Time : 2018/6/21 9:12
- # @Author : Py.qi
- # @File : req_session.py
- # @Software: PyCharm
- import requests
- from requests.auth import HTTPBasicAuth
- url='http://192.168.146.140/admin/'
- s=requests.Session()
- response=s.get(url,auth=HTTPBasicAuth('admin',''))
- print(response.text)
- print(response.headers)
- print(response.status_code)
8、SSL证书验证
rerquests提供了证书验证的功能,当发送http请求时,它会检查SSL证书,可以通过verify参数来控制是否检查此证书,如果不设置默认为True会自动验证,我们使用https://www.12306.cn测试
- import requests
- r=requests.get('https://www.12306.cn')
- print(r.status_code)
- #返回SSLError
- raise SSLError(e, request=request)
将verify参数设置为false在看结果:
- import requests
- r=requests.get('https://www.12306.cn',verify=False)
- print(r.status_code)
- #能正常返回200,但有个警告信息
- D:\virtualenv-36\.venv\lib\site-packages\urllib3\connectionpool.py:857: InsecureRequestWarning: Unverified HTTPS request is being made. Adding certificate verification is strongly advised. See: https://urllib3.readthedocs.io/en/latest/advanced-usage.html#ssl-warnings
- InsecureRequestWarning)
- 200
可以使用urllib3中的disable_warnings()忽略警告,也可以用logging日子模块将警告写入日志
- import requests
- import logging
- import urllib3
- urllib3.disable_warnings() #忽略警告
- #logging.captureWarnings(True) #也可以写入日志中
- r=requests.get('https://www.12306.cn',verify=False)
- print(r.status_code)
- #
- 200
除了以上的方法,我们如果有证书的话,可以cert参数指定证书路径,如果是单个文件包含密钥和证书,也可以设置两个文件路径的元祖分别指向证书和密钥
- import requests
- response = requests.get('https://www.12306.cn', cert=('/path/server.crt', '/path/key'))
- print(response.status_code)
- #注意,如果是本地私有证书的key必须是解密状态,加密状态的key是不支持的
9、代理设置
对于某些网站,在测试的时候请求几次,能正常获取内容。但是一旦开始大规模爬取,对于大规模且频繁的请求,网站可能会弹出验证码,或者跳转到登录认证页面,更甚者可能会直接封禁客户端的IP,导致一定时间段内无法访问。
那么,为了防止这种情况发生,我们需要设置代理来解决这个问题,这就需要用到proxies
参数
- import requests
- proxies = {
- "http": "http://10.10.1.10:3128",
- "https": "http://10.10.1.10:1080",
- }
- requests.get("https://www.taobao.com", proxies=proxies)
若代理需要使用HTTP Basic Auth,可以使用类似http://user:password@host:port这样的语法来设置代理
- import requests
- proxies = {
- "http": "http://user:password@10.10.1.10:3128/",
- }
- requests.get("https://www.taobao.com", proxies=proxies)
除了基本的HTTP代理外,requests还支持SOCKS协议的代理
这是一个可选功能,需要在使用前安装额外的第三方库
您可以从以下位置获取此功能的依赖关系
- $ pip install requests[socks]
一旦你安装了这些依赖项,使用SOCKS代理就像使用HTTP代理一样简单:
- import requests
- proxies = {
- 'http': 'socks5://user:password@host:port',
- 'https': 'socks5://user:password@host:port'
- }
- requests.get("https://www.taobao.com", proxies=proxies)
使用该方案socks5
会导致DNS解析发生在客户端上,而不是在代理服务器上,它使用该方案来决定是否在客户端或代理上执行DNS解析。如果要解析代理服务器上的域,请使用socks5h
该方案。
10、身份认证
如果访问的网站需要身份认证的话,可以使用requests自带的身份认证功能,其中包括四个类:
class requests.auth.AuthBase:所有auth实现派生自的基类
class requests.auth.HTTPBasicAuth(username, password):将HTTP基本认证附加到给定的请求对象
class requests.auth.HTTPProxyAuth(username, password):将HTTP代理身份验证附加到给定的请求对象
class requests.auth.HTTPDigestAuth(username, password):将HTTP摘要式身份验证附加到给定的请求对象
基本认证:
- import requests
- from requests.auth import HTTPBasicAuth
- url='http://192.168.146.140/admin/'
- s=requests.Session()
- auth=HTTPBasicAuth('admin','') #创建密码认证对象
- response=s.get(url,auth=auth) #附加认证信息
- print(response.text)
代理身份验证:
- #!/usr/bin/env python
- # -*- coding: utf-8 -*-
- # @Time : 2018/6/21 10:36
- # @Author : Py.qi
- # @File : req_proxauth.py
- # @Software: PyCharm
- import requests
- from requests.auth import HTTPProxyAuth
- proauth=HTTPProxyAuth(username='admin',password='')
- proxies={
- 'http':'10.0.0.10:3324'
- }
- s=requests.Session() #创建session对象
- s.trust_env=proauth #添加代理身份验证
- s.proxies=proxies #添加代理URL
- response=s.get('https://www.facebook.com')
- print(response.text)
11、编码
当您收到响应时,请求会在您访问Response.text
属性时猜测用于解码响应的编码。请求将首先检查HTTP标头中的编码,如果不存在,将使用chardet通用字符编码检测器,来尝试猜测编码,如果没有明确的字符集是存在于HTTP头,并在Content-Type
头中包含text
。在这种情况下,RFC 2616指定默认字符集必须是ISO-8859-1
。在这种情况下,请求遵循规范。如果你需要不同的编码,你可以手动设置Response.encoding
属性,或者使用原始的Response.content
。
requests.utils.get_encodings_from_content(content):从给定的内容字符串返回编码
requests.utils.get_encoding_from_headers(headers):从给定的HTTP标题字典返回编码,headers头文件字典,返回str
requests.utils.get_unicode_from_response(r):以unicode形式返回请求的内容,r是响应对象,返回str
- #!/usr/bin/env python
- # -*- coding: utf-8 -*-
- # @Time : 2018/6/21 11:46
- # @Author : Py.qi
- # @File : req_enconding.py
- # @Software: PyCharm
- import requests
- from requests.utils import get_encodings_from_content
- from requests.utils import get_encoding_from_headers
- from requests.utils import get_unicode_from_response
- r=requests.get('http://cnblogs.com')
- print(get_encodings_from_content(r.text)) #从内容中返回编码
- print(get_encoding_from_headers(r.headers)) #从头文件中返回编码
- print(get_unicode_from_response(r)) #unicode返回请求内容
- #
- ['utf-8']
- utf-8
- <!DOCTYPE html>
- <html lang="zh-cn">
- <head>
- <meta charset="utf-8" />
- <meta name="viewport" content="width=device-width, initial-scale=1" />
- <meta name="referrer" content="always" />
- <title>博客园 - 开发者的网上家园</title>.............
12、其他说明
(1)状态码
requests.codes 该codes对象定义了从http状态中通过名称映射的数字代码的状态码,可以作为属性或字典访问
- import requests
- print(requests.codes['forbidden']) #
- print(requests.codes['ok']) #
- print(requests.codes['not_modified']) #
- print(requests.codes['not_found']) #
- print(requests.codes['internal_server_error']) #
(2)超时设置
如果服务器没有及时响应,大多数对外部服务器的请求应该附加一个超时值。默认情况下,除非显式设置超时值,否则请求不会超时。如果没有超时,您的代码可能会挂起几分钟或更长时间。
一旦你的客户端连接到服务器并发送了HTTP请求, 读取超时就是客户端等待服务器发送响应的秒数
为超时指定单个值,如下所示:
- r = requests.get('https://github.com', timeout=5)
超时值将应用于 超时connect
和read
超时。如果您想单独设置值,请指定一个元组:
- r = requests.get('https://github.com', timeout=(3.05, 27))
如果远程服务器速度非常慢,您可以通过将None作为超时值,让“请求”永久等待响应:
- r = requests.get('https://github.com', timeout=None)
(3)流媒体请求
可以使用iter_content方法迭代获取数据,或者使用iter_line(),但在构建请求是需要指定stream=True来返回流内容数据
- #!/usr/bin/env python
- # -*- coding: utf-8 -*-
- # @Time : 2018/6/21 12:38
- # @Author : Py.qi
- # @File : req_block.py
- # @Software: PyCharm
- import requests
- import json
- r=requests.get('http://httpbin.org/stream/20',stream=True)
- for i in r.iter_content(chunk_size=1024,decode_unicode=True):
- if i:
- print(json.loads(i.decode()))
抓取网页内容实例:
- #!/usr/bin/env python
- #coding:utf-8
- import json
- from multiprocessing import Pool
- from requests.exceptions import RequestException
- import requests
- import re
- #类建立初始化
- class get_parse(object):
- _headers = {
- 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.79 Safari/537.36'}
- _pattern = re.compile(
- '<dd>.*?board-index.*?>(\d+)</i>.*?data-src="(.*?)".*?name.*?a.*?>(.*?)</a>.*?star.*?>(.*?)</p>.*?releasetime.*?>(.*?)</p>.*?integer.*?>(.*?)</i>.*?fraction.*?>(.*?)</i>.*?</dd>',
- re.S)
- def __init__(self,url):
- self.url=url
- #方法返回一个生成器
- def get_page(self):
- try:
- response = requests.get(self.url, headers=self._headers)
- if response.status_code == 200:
- body=response.text
- items=re.findall(self._pattern,body)
- for j in items:
- dic = {}
- for i in range(len(j)):
- dic['id']=j[0]
- dic['image']=j[1]
- dic['title']=j[2]
- dic['actor']=j[3].strip()
- dic['time']=j[4].strip()
- dic['score']=j[5]+j[6]
- yield dic
- except RequestException as e:
- return e
- #类方法抓取内容写入到文件
- def write_file(self,data):
- with open('resule.txt','a',encoding='utf-8') as f:
- f.write(json.dumps(data,ensure_ascii=False) + '\n')
- f.close()
- #函数返回一个页面的内容
- def main(offset):
- url='http://maoyan.com/board/4?offset=' + str(offset)
- data=get_parse(url)
- result=data.get_page()
- for item in result:
- print(item)
- data.write_file(item) #调用方法写入到文件
- if __name__ == '__main__':
- #for i in range(10):
- #main(offset=i*10)
- pool = Pool() #建立进程池
- pool.map(main, [i * 10 for i in range(10)]) #多进程运行函数,map和内置函数原理一样
更多关于requests使用请查看官网
-----------------------------------------end
python3之requests的更多相关文章
- python3使用requests登录人人影视网站
python3使用requests登录人人影视网站 继续练习使用requests登录网站,人人影视有一项功能是签到功能,需要每天登录签到才能升级. 下面的代码python代码实现了使用requests ...
- python3使用requests发闪存
闪存ing.cnblogs.com是博客园类似推特.饭否的服务, 我写了以下程序可以完成发闪存的操作,目的是顺便练习使用requests库. requests是一个python 轻量的http客户端库 ...
- Python3下requests库发送multipart/form-data类型请求
[本文出自天外归云的博客园] 要模拟multipart/form-data类型请求,可以用python3的requests库完成.代码示例如下: #请求的接口url url = "url&q ...
- Python3:Requests模块的异常值处理
Python3:Requests模块的异常值处理 用Python的requests模块进行爬虫时,一个简单高效的模块就是requests模块,利用get()或者post()函数,发送请求. 但是在真正 ...
- Python3之Requests模块详解
# 导入 Request模块 # 若本机无自带Request模块,可自行下载或者使用pip进行安装 # python版本Python3 import requests import json #### ...
- python3使用requests爬取新浪热门微博
微博登录的实现代码来源:https://gist.github.com/mrluanma/3621775 相关环境 使用的python3.4,发现配置好环境后可以直接使用pip easy_instal ...
- [实战演练]python3使用requests模块爬取页面内容
本文摘要: 1.安装pip 2.安装requests模块 3.安装beautifulsoup4 4.requests模块浅析 + 发送请求 + 传递URL参数 + 响应内容 + 获取网页编码 + 获取 ...
- python3使用requests模块完成get/post/代理/自定义header/自定义Cookie
一.背景说明 http请求的难易对一门语言来说是很重要的而且是越来越重要,但对于python一是urllib一些写法不太符合人的思维习惯文档也相当难看,二是在python2.x和python3.x中写 ...
- python3+selenium3+requests爬取我的博客粉丝的名称
爬取目标 1.本次代码是在python3上运行通过的 selenium3 +firefox59.0.1(最新) BeautifulSoup requests 2.爬取目标网站,我的博客:https:/ ...
随机推荐
- rt-thread learning notes
rt-thread learning notes 2018-01-15 > 001 具有相同优先级的线程,每个线程的时间片大小都可以在初始化或创建该线程时指定 rt_thread_t rt_th ...
- yum 安装Mysql
RHEL6.5-MySql-yum安装登录 客户端工具的使用mysql:Linux下提供了一个访问mysql服务器的客户端工具—mysql,其由mysql软件包提供,除了这些工具之外还有一些图形化界面 ...
- luogu3295 萌萌哒 (并查集+ST表)
如果给相同的位置连边,最后联通块数是n,最后答案就是$9*10^{n-1}$ 但直接连边是$O(n^2)$的 所以事先处理出一个ST表,每次O(1)地给那个ST表连边 最后再一点一点下放,就是把在这层 ...
- CodeForces - 669D
题目链接:http://codeforces.com/problemset/problem/669/D Little Artem is fond of dancing. Most of all dan ...
- MATLAB:图像的移动(move函数)
图像移动涉及到move函数,实现过程如下: close all; %关闭当前所有图形窗口,清空工作空间变量,清除工作空间所有变量 clear all; clc; I=imread('lenna.bmp ...
- 02-HTML5新的input属性
本节重点 HTML5 拥有多个新的表单输入类型.这些新特性提供了更好的输入控制和验证 本节介绍新的输入类型: date datetime datetime-local email month numb ...
- shiro+SpringMVC 项目 配置404页面
说的配置404,大家都会想到去web.xml里面配置 <error-page> <error-code></error-code> <location> ...
- Study 2 —— 格式化输出
打印人物信息的两种方法第一种: Name = input('Input your name: ') Age = input('Input your age: ') Job = input('Input ...
- windows递归复制指定时间后修改过的文件
因为在拷贝web站点时,也会存在更新,需要定期覆盖新的内容,就是上次覆盖的时间和到这次时间内修改过的文件都复制. 实现命令xcopy xcopy src dest D:\WWW\phpMyAdmin\ ...
- POJ 2443 Set Operation
Set Operation Time Limit: 3000MS Memory Limit: 65536K Total Submissions: 3558 Accepted: 1479 Des ...