Python——requests模块详解
Posted 程序员老华
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Python——requests模块详解相关的知识,希望对你有一定的参考价值。
1、模块说明
requests是使用Apache2 licensed 许可证的HTTP库。
用python编写。
比urllib2模块更简洁。
Request支持HTTP连接保持和连接池,支持使用cookie保持会话,支持文件上传,支持自动响应内容的编码,支持国际化的URL和POST数据自动编码。
在python内置模块的基础上进行了高度的封装,从而使得python进行网络请求时,变得人性化,使用Requests可以轻而易举的完成浏览器可有的任何操作。
现代,国际化,友好。
requests会自动实现持久连接keep-alive
2、基础入门
1)导入模块
import requests
2)发送请求的简洁
示例代码:获取一个网页(个人github)
import requests r = requests.get('https://github.com/Ranxf') # 最基本的不带参数的get请求 r1 = requests.get(url='http://dict.baidu.com/s', params='wd': 'python') # 带参数的get请求
我们就可以使用该方式使用以下各种方法
1 requests.get(‘https://github.com/timeline.json’) # GET请求 2 requests.post(“http://httpbin.org/post”) # POST请求 3 requests.put(“http://httpbin.org/put”) # PUT请求 4 requests.delete(“http://httpbin.org/delete”) # DELETE请求 5 requests.head(“http://httpbin.org/get”) # HEAD请求 6 requests.options(“http://httpbin.org/get” ) # OPTIONS请求
3)为url传递参数
>>> url_params = 'key':'value' # 字典传递参数,如果值为None的键不会被添加到url中 >>> r = requests.get('your url',params = url_params) >>> print(r.url) your url?key=value
4)响应的内容
r.encoding #获取当前的编码 r.encoding = 'utf-8' #设置编码 r.text #以encoding解析返回内容。字符串方式的响应体,会自动根据响应头部的字符编码进行解码。 r.content #以字节形式(二进制)返回。字节方式的响应体,会自动为你解码 gzip 和 deflate 压缩。 r.headers #以字典对象存储服务器响应头,但是这个字典比较特殊,字典键不区分大小写,若键不存在则返回None r.status_code #响应状态码 r.raw #返回原始响应体,也就是 urllib 的 response 对象,使用 r.raw.read() r.ok # 查看r.ok的布尔值便可以知道是否登陆成功 #*特殊方法*# r.json() #Requests中内置的JSON解码器,以json形式返回,前提返回的内容确保是json格式的,不然解析出错会抛异常 r.raise_for_status() #失败请求(非200响应)抛出异常
post发送json请求:
1 import requests 2 import json 3 4 r = requests.post('https://api.github.com/some/endpoint', data=json.dumps('some': 'data')) 5 print(r.json())
5)定制头和cookie信息
header = 'user-agent': 'my-app/0.0.1'' cookie = 'key':'value' r = requests.get/post('your url',headers=header,cookies=cookie)
data = 'some': 'data' headers = 'content-type': 'application/json', 'User-Agent': 'Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:22.0) Gecko/20100101 Firefox/22.0' r = requests.post('https://api.github.com/some/endpoint', data=data, headers=headers) print(r.text)
6)响应状态码
使用requests方法后,会返回一个response对象,其存储了服务器响应的内容,如上实例中已经提到的 r.text、r.status_code……
获取文本方式的响应体实例:当你访问 r.text 之时,会使用其响应的文本编码进行解码,并且你可以修改其编码让 r.text 使用自定义的编码进行解码。
1 r = requests.get('http://www.itwhy.org') 2 print(r.text, '\\n\\n'.format('*'*79), r.encoding) 3 r.encoding = 'GBK' 4 print(r.text, '\\n\\n'.format('*'*79), r.encoding)
示例代码:
1 import requests 2 3 r = requests.get('https://github.com/Ranxf') # 最基本的不带参数的get请求 4 print(r.status_code) # 获取返回状态 5 r1 = requests.get(url='http://dict.baidu.com/s', params='wd': 'python') # 带参数的get请求 6 print(r1.url) 7 print(r1.text) # 打印解码后的返回数据
运行结果:
/usr/bin/python3.5 /home/rxf/python3_1000/1000/python3_server/python3_requests/demo1.py 200 http://dict.baidu.com/s?wd=python ………… Process finished with exit code 0
r.status_code #如果不是200,可以使用 r.raise_for_status() 抛出异常
7)响应
r.headers #返回字典类型,头信息 r.requests.headers #返回发送到服务器的头信息 r.cookies #返回cookie r.history #返回重定向信息,当然可以在请求是加上allow_redirects = false 阻止重定向
8)超时
r = requests.get('url',timeout=1) #设置秒数超时,仅对于连接有效
9)会话对象,能够跨请求保持某些参数
s = requests.Session() s.auth = ('auth','passwd') s.headers = 'key':'value' r = s.get('url') r1 = s.get('url1')
10)代理
proxies = 'http':'ip1','https':'ip2' requests.get('url',proxies=proxies)
汇总:
# HTTP请求类型 # get类型 r = requests.get('https://github.com/timeline.json') # post类型 r = requests.post("http://m.ctrip.com/post") # put类型 r = requests.put("http://m.ctrip.com/put") # delete类型 r = requests.delete("http://m.ctrip.com/delete") # head类型 r = requests.head("http://m.ctrip.com/head") # options类型 r = requests.options("http://m.ctrip.com/get") # 获取响应内容 print(r.content) #以字节的方式去显示,中文显示为字符 print(r.text) #以文本的方式去显示 #URL传递参数 payload = 'keyword': '香港', 'salecityid': '2' r = requests.get("http://m.ctrip.com/webapp/tourvisa/visa_list", params=payload) print(r.url) #示例为http://m.ctrip.com/webapp/tourvisa/visa_list?salecityid=2&keyword=香港 #获取/修改网页编码 r = requests.get('https://github.com/timeline.json') print (r.encoding) #json处理 r = requests.get('https://github.com/timeline.json') print(r.json()) # 需要先import json # 定制请求头 url = 'http://m.ctrip.com' headers = 'User-Agent' : 'Mozilla/5.0 (Linux; android 4.2.1; en-us; Nexus 4 Build/JOP40D) AppleWebKit/535.19 (Khtml, like Gecko) Chrome/18.0.1025.166 Mobile Safari/535.19' r = requests.post(url, headers=headers) print (r.request.headers) #复杂post请求 url = 'http://m.ctrip.com' payload = 'some': 'data' r = requests.post(url, data=json.dumps(payload)) #如果传递的payload是string而不是dict,需要先调用dumps方法格式化一下 # post多部分编码文件 url = 'http://m.ctrip.com' files = 'file': open('report.xls', 'rb') r = requests.post(url, files=files) # 响应状态码 r = requests.get('http://m.ctrip.com') print(r.status_code) # 响应头 r = requests.get('http://m.ctrip.com') print (r.headers) print (r.headers['Content-Type']) print (r.headers.get('content-type')) #访问响应头部分内容的两种方式 # Cookies url = 'http://example.com/some/cookie/setting/url' r = requests.get(url) r.cookies['example_cookie_name'] #读取cookies url = 'http://m.ctrip.com/cookies' cookies = dict(cookies_are='working') r = requests.get(url, cookies=cookies) #发送cookies #设置超时时间 r = requests.get('http://m.ctrip.com', timeout=0.001) #设置访问代理 proxies = "http": "http://10.10.1.10:3128", "https": "http://10.10.1.100:4444", r = requests.get('http://m.ctrip.com', proxies=proxies) #如果代理需要用户名和密码,则需要这样: proxies = "http": "http://user:pass@10.10.1.10:3128/",
# HTTP请求类型 # get类型 r = requests.get('https://github.com/timeline.json') # post类型 r = requests.post("http://m.ctrip.com/post") # put类型 r = requests.put("http://m.ctrip.com/put") # delete类型 r = requests.delete("http://m.ctrip.com/delete") # head类型 r = requests.head("http://m.ctrip.com/head") # options类型 r = requests.options("http://m.ctrip.com/get") # 获取响应内容 print(r.content) #以字节的方式去显示,中文显示为字符 print(r.text) #以文本的方式去显示 #URL传递参数 payload = 'keyword': '香港', 'salecityid': '2' r = requests.get("http://m.ctrip.com/webapp/tourvisa/visa_list", params=payload) print(r.url) #示例为http://m.ctrip.com/webapp/tourvisa/visa_list?salecityid=2&keyword=香港 #获取/修改网页编码 r = requests.get('https://github.com/timeline.json') print (r.encoding) #json处理 r = requests.get('https://github.com/timeline.json') print(r.json()) # 需要先import json # 定制请求头 url = 'http://m.ctrip.com' headers = 'User-Agent' : 'Mozilla/5.0 (Linux; Android 4.2.1; en-us; Nexus 4 Build/JOP40D) AppleWebKit/535.19 (KHTML, like Gecko) Chrome/18.0.1025.166 Mobile Safari/535.19' r = requests.post(url, headers=headers) print (r.request.headers) #复杂post请求 url = 'http://m.ctrip.com' payload = 'some': 'data' r = requests.post(url, data=json.dumps(payload)) #如果传递的payload是string而不是dict,需要先调用dumps方法格式化一下 # post多部分编码文件 url = 'http://m.ctrip.com' files = 'file': open('report.xls', 'rb') r = requests.post(url, files=files) # 响应状态码 r = requests.get('http://m.ctrip.com') print(r.status_code) # 响应头 r = requests.get('http://m.ctrip.com') print (r.headers) print (r.headers['Content-Type']) print (r.headers.get('content-type')) #访问响应头部分内容的两种方式 # Cookies url = 'http://example.com/some/cookie/setting/url' r = requests.get(url) r.cookies['example_cookie_name'] #读取cookies url = 'http://m.ctrip.com/cookies' cookies = dict(cookies_are='working') r = requests.get(url, cookies=cookies) #发送cookies #设置超时时间 r = requests.get('http://m.ctrip.com', timeout=0.001) #设置访问代理 proxies = "http": "http://10.10.1.10:3128", "https": "http://10.10.1.100:4444", r = requests.get('http://m.ctrip.com', proxies=proxies) #如果代理需要用户名和密码,则需要这样: proxies = "http": "http://user:pass@10.10.1.10:3128/",
3、示例代码
GET请求
1 # 1、无参数实例 2 3 import requests 4 5 ret = requests.get('https://github.com/timeline.json') 6 7 print(ret.url) 8 print(ret.text) 9 10 11 12 # 2、有参数实例 13 14 import requests 15 16 payload = 'key1': 'value1', 'key2': 'value2' 17 ret = requests.get("http://httpbin.org/get", params=payload) 18 19 print(ret.url) 20 print(ret.text)
POST请求
# 1、基本POST实例 import requests payload = 'key1': 'value1', 'key2': 'value2' ret = requests.post("http://httpbin.org/post", data=payload) print(ret.text) # 2、发送请求头和数据实例 import requests import json url = 'https://api.github.com/some/endpoint' payload = 'some': 'data' headers = 'content-type': 'application/json' ret = requests.post(url, data=json.dumps(payload), headers=headers) print(ret.text) print(ret.cookies)
json请求:
#! /usr/bin/python3 import requests import json class url_request(): def __init__(self): ''' init ''' if __name__ == '__main__': heard = 'Content-Type': 'application/json' payload = 'CountryName': '中国', 'ProvinceName': '四川省', 'L1CityName': 'chengdu', 'L2CityName': 'yibing', 'TownName': '', 'Longitude': '107.33393', 'Latitude': '33.157131', 'Language': 'CN' r = requests.post("http://www.xxxxxx.com/CityLocation/json/LBSLocateCity", heards=heard, data=payload) data = r.json() if r.status_code!=200: print('LBSLocateCity API Error' + str(r.status_code)) print(data['CityEntities'][0]['CityID']) # 打印返回json中的某个key的value print(data['ResponseStatus']['Ack']) print(json.dump(data, indent=4, sort_keys=True, ensure_ascii=False)) # 树形打印json,ensure_ascii必须设为False否则中文会显示为unicode
Xml请求:
#! /usr/bin/python3 import requests class url_request(): def __init__(self): """init""" if __name__ == '__main__': heards = 'Content-type': 'text/xml' XML = '<?xml version="1.0" encoding="utf-8"?><soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"><soap:Body><Request xmlns="http://tempuri.org/"><jme><JobClassFullName>WeChatJSTicket.JobWS.Job.JobRefreshTicket,WeChatJSTicket.JobWS</JobClassFullName><Action>RUN</Action><Param>1</Param><HostIP>127.0.0.1</HostIP><JobInfo>1</JobInfo><NeedParallel>false</NeedParallel></jme></Request></soap:Body></soap:Envelope>' url = 'http://jobws.push.mobile.xxxxxxxx.com/RefreshWeiXInTokenJob/RefreshService.asmx' r = requests.post(url=url, heards=heards, data=XML) data = r.text print(data)
状态异常处理
import requests URL = 'http://ip.taobao.com/service/getIpInfo.php' # 淘宝IP地址库API try: r = requests.get(URL, params='ip': '8.8.8.8', timeout=1) r.raise_for_status() # 如果响应状态码不是 200,就主动抛出异常 except requests.RequestException as e: print(e) else: result = r.json() print(type(result), result, sep='\\n')
上传文件
使用request模块,也可以上传文件,文件的类型会自动进行处理:
import requests url = 'http://127.0.0.1:8080/upload' files = 'file': open('/home/rxf/test.jpg', 'rb') #files = 'file': ('report.jpg', open('/home/lyb/sjzl.mpg', 'rb')) #显式的设置文件名 r = requests.post(url, files=files) print(r.text)
request更加方便的是,可以把字符串当作文件进行上传:
import requests url = 'http://127.0.0.1:8080/upload' files = 'file': ('test.txt', b'Hello Requests.') #必需显式的设置文件名 r = requests.post(url, files=files) print(r.text)
6) 身份验证
基本身份认证(HTTP Basic Auth)
import requests from requests.auth import HTTPBasicAuth r = requests.get('https://httpbin.org/hidden-basic-auth/user/passwd', auth=HTTPBasicAuth('user', 'passwd')) # r = requests.get('https://httpbin.org/hidden-basic-auth/user/passwd', auth=('user', 'passwd')) # 简写 print(r.json())
另一种非常流行的HTTP身份认证形式是摘要式身份认证,Requests对它的支持也是开箱即可用的:
requests.get(URL, auth=HTTPDigestAuth('user', 'pass')
Cookies与会话对象
如果某个响应中包含一些Cookie,你可以快速访问它们:
import requests r = requests.get('http://www.google.com.hk/') print(r.cookies['NID']) print(tuple(r.cookies))
要想发送你的cookies到服务器,可以使用 cookies 参数:
import requests url = 'http://httpbin.org/cookies' cookies = 'testCookies_1': 'Hello_Python3', 'testCookies_2': 'Hello_Requests' # 在Cookie Version 0中规定空格、方括号、圆括号、等于号、逗号、双引号、斜杠、问号、@,冒号,分号等特殊符号都不能作为Cookie的内容。 r = requests.get(url, cookies=cookies) print(r.json())
会话对象让你能够跨请求保持某些参数,最方便的是在同一个Session实例发出的所有请求之间保持cookies,且这些都是自动处理的,甚是方便。
下面就来一个真正的实例,如下是快盘签到脚本:
requests模块抓取网页源码并保存到文件示例
这是一个基本的文件保存操作,但这里有几个值得注意的问题:
1.安装requests包,命令行输入pip install requests即可自动安装。很多人推荐使用requests,自带的urllib.request也可以抓取网页源码
2.open方法encoding参数设为utf-8,否则保存的文件会出现乱码。
3.如果直接在cmd中输出抓取的内容,会提示各种编码错误,所以保存到文件查看。
4.with open方法是更好的写法,可以自动操作完毕后释放资源
#! /urs/bin/python3 import requests '''requests模块抓取网页源码并保存到文件示例''' html = requests.get("http://www.baidu.com") with open('test.txt', 'w', encoding='utf-8') as f: f.write(html.text) '''读取一个txt文件,每次读取一行,并保存到另一个txt文件中的示例''' ff = open('testt.txt', 'w', encoding='utf-8') with open('test.txt', encoding="utf-8") as f: for line in f: ff.write(line) ff.close()
因为在命令行中打印每次读取一行的数据,中文会出现编码错误,所以每次读取一行并保存到另一个文件,这样来测试读取是否正常。(注意open的时候制定encoding编码方式)
详解:Python2中的urlliburllib2与Python3中的urllib以及第三方模块requests
先说说Python2中的url与urllib2(参考此处):
在python2中,urllib和urllib2都是接受URL请求的相关模块,但是提供了不同的功能。两个最显著的不同如下:
1、urllib2可以接受一个Request类的实例来设置URL请求的headers,例如:
req = urllib2.Request(
url=url,
data=postdata,
headers=headers
)
result = urllib2.urlopen(req)
我们知道,HTTP是无连接的状态协议,但是客户端和服务器端需要保持一些相互信息,比如cookie,有了cookie,服务器才能知道刚才是这个用户登录了网站,才会给予客户端访问一些页面的权限。所以我们需要保存cookie,之后附带cookie再来访问网站,才能够达到效果。这里就需要Python的cookielib和urllib2等的配合,将cookielib绑定到urllib2在一起,就能够在请求网页的时候附带cookie。在构造req请求之前可以获取一个保存cookies的对象,并把该对象和http处理器、http的handler资源以及urllib2的对象绑定在一起:
cj = cookielib.LWPCookieJar()
cookie_support = urllib2.HTTPCookieProcessor(cj)
# 创建一个opener,将保存了cookie的http处理器,还有设置一个handler用于处理http的URL的打开
opener = urllib2.build_opener(cookie_support, urllib2.HTTPHandler)
# 将包含了cookie、http处理器、http的handler的资源和urllib2对象板顶在一起
urllib2.install_opener(opener)
2、urllib仅可以接受URL。这意味着,你不可以伪装你的User Agent字符串等。
但是urllib提供urlencode方法用来GET查询字符串的产生,而urllib2没有。这是就是为何urllib常和urllib2一起使用的原因,如下:
postdata = urllib.urlencode(postdata)
(把字典形式的postdata编码一下)
Tip: if you are planning to do HTTP stuff only, check out httplib2, it is much better than httplib or urllib or urllib2.
》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》
下面说说Python3x中的urllib包、http包以及其他比较好使的第三方包
1、Python3 urllib、http
Python3不像2x中酷虎的和服务器模块结构散乱,Python3中把这些打包成为了2个包,就是http与urllib,详解如下:
http会处理所有客户端--服务器http请求的具体细节,其中:
(1)client会处理客户端的部分
(2)server会协助你编写Python web服务器程序
(3)cookies和cookiejar会处理cookie,cookie可以在请求中存储数据
使用cookiejar示例可以在前几篇博客中基于Python3的爬虫中找到示例,如下:
import http.cookiejar
import urllib.request
import urllib.parse</span></span>
def getOpener(head):
# deal with the Cookies
cj = http.cookiejar.CookieJar()
pro = urllib.request.HTTPCookieProcessor(cj)
opener = urllib.request.build_opener(pro)
header = []
for key, value in head.items():
elem = (key, value)
header.append(elem)
opener.addheaders = header
return opener
urllib是基于http的高层库,它有以下三个主要功能:
(1)request处理客户端的请求
(2)response处理服务端的响应
(3)parse会解析url
下面是使用Python3中urllib来获取资源的一些示例:
1、最简单
import urllib.request
response = urllib.request.urlopen('http://python.org/')
html = response.read()
2、使用 Request
import urllib.request
req = urllib.request.Request('http://python.org/')
response = urllib.request.urlopen(req)
the_page = response.read()
3、发送数据
import urllib.parse
import urllib.request
url = '"
values =
'act' : 'login',
'login[email]' : '',
'login[password]' : ''
data = urllib.parse.urlencode(values)
req = urllib.request.Request(url, data)
req.add_header('Referer', 'http://www.python.org/')
response = urllib.request.urlopen(req)
the_page = response.read()
print(the_page.decode("utf8"))
4、发送数据和header
import urllib.parse
import urllib.request
url = ''
user_agent = 'Mozilla/4.0 (compatible; MSIE 5.5; Windows NT)'
values =
'act' : 'login',
'login[email]' : '',
'login[password]' : ''
headers = 'User-Agent' : user_agent
data = urllib.parse.urlencode(values)
req = urllib.request.Request(url, data, headers)
response = urllib.request.urlopen(req)
the_page = response.read()
print(the_page.decode("utf8"))
5、http 错误
import urllib.request
req = urllib.request.Request(' ')
try:
urllib.request.urlopen(req)
except urllib.error.HTTPError as e:
print(e.code)
print(e.read().decode("utf8"))
6、异常处理1
from urllib.request import Request, urlopen
from urllib.error import URLError, HTTPError
req = Request("http://www..net /")
try:
response = urlopen(req)
except HTTPError as e:
print('The server couldn't fulfill the request.')
print('Error code: ', e.code)
except URLError as e:
print('We failed to reach a server.')
print('Reason: ', e.reason)
else:
print("good!")
print(response.read().decode("utf8"))
7、异常处理2
from urllib.request import Request, urlopen
from urllib.error import URLError
req = Request("http://www.Python.org/")
try:
response = urlopen(req)
except URLError as e:
if hasattr(e, 'reason'):
print('We failed to reach a server.')
print('Reason: ', e.reason)
elif hasattr(e, 'code'):
print('The server couldn't fulfill the request.')
print('Error code: ', e.code)
else:
print("good!")
print(response.read().decode("utf8"))
8、HTTP 认证
import urllib.request
# create a password manager
password_mgr = urllib.request.HTTPPasswordMgrWithDefaultRealm()
# Add the username and password.
# If we knew the realm, we could use it instead of None.
top_level_url = ""
password_mgr.add_password(None, top_level_url, 'rekfan', 'xxxxxx')
handler = urllib.request.HTTPBasicAuthHandler(password_mgr)
# create "opener" (OpenerDirector instance)
opener = urllib.request.build_opener(handler)
# use the opener to fetch a URL
a_url = ""
x = opener.open(a_url)
print(x.read())
# Install the opener.
# Now all calls to urllib.request.urlopen use our opener.
urllib.request.install_opener(opener)
a = urllib.request.urlopen(a_url).read().decode('utf8')
print(a)
9、使用代理
import urllib.request
proxy_support = urllib.request.ProxyHandler('sock5': 'localhost:1080')
opener = urllib.request.build_opener(proxy_support)
urllib.request.install_opener(opener)
a = urllib.request.urlopen("").read().decode("utf8")
print(a)
10、超时
import socket
import urllib.request
# timeout in seconds
timeout = 2
socket.setdefaulttimeout(timeout)
# this call to urllib.request.urlopen now uses the default timeout
# we have set in the socket module
req = urllib.request.Request('')
a = urllib.request.urlopen(req).read()
print(a)
上面例子大概把常用的一些情况都罗列出来了,其中对异常的处理要严格按照:
try...exceptA...exceptB...except...else...finally...
的语法格式来写,详情请参考我的另一篇相关博文
》》》》》》》》》》》》》》》》》》》》》》》》
2、除了使用官方标准库的urllib,我们可以使用更好用的第三方模块,如requests
Requests 完全满足如今网络的需求,其功能有以下:
- 国际化域名和 URLs
- Keep-Alive & 连接池
- 持久的 Cookie 会话
- 类浏览器式的 SSL 加密认证
- 基本/摘要式的身份认证
- 优雅的键/值 Cookies
- 自动解压
- Unicode 编码的响应体
- 多段文件上传
- 连接超时
- 支持
.netrc
- 适用于 Python 2.6—3.4
- 线程安全
请参考中文官方文档,写的非常详细:传送门
其中快速上手页面写的非常棒,我就不赘述了,请看:传送门
正如介绍所说:Requests 是使用 Apache2 Licensed 许可证的 HTTP 库。用 Python 编写,真正的为人类着想。
以上是关于Python——requests模块详解的主要内容,如果未能解决你的问题,请参考以下文章