python requests Python用Requests发请求,简直爽到飞起,urllib哭晕在厕所
介绍
首先让我们来看 官方的介绍:
Requests is an elegant and simple HTTP library for Python, built for human beings.翻成过来意思是: 是给人类所撰写的一个具备优雅特性且呈现简单状态的 HTTP 库。如今这段介绍已经足够直白明显 , 那就让我们首先率先去领略一番其威势力量。
import requests # 发送请求 response = requests.get(url="http://www.baidu.com/s", params={'wd':'python'}) # 处理响应 print(response.status_code) # 输出结果 200这个请求如果用 来实现,代码如下:
import urllib.parse import urllib.request url = "http://www.baidu.com/s" params = urllib.parse.urlencode({'wd':'python'}) # 发送请求 response = urllib.request.urlopen('?'.join([url, params])) # 处理响应 print(response.getcode()) # 输出结果 200就从感官方面而言, 是能够瞧出来的, 运用起来, 于URL、参数等层面会繁杂一些。这仅仅只是冰山一角罢了, 在实际运用进程当中, 还存有好多层面超出, 它并非是徒有虚名, 在接下来的学习期间, 你便会体会到。
安装
使用pip命令
$ pip3 install requests或者也可以使用 命令安装
$ easy_install requests发送请求
使用 发送网络请求非常简单。
我们首先需要导入 模块:
import requests而后, 我们能够试着去获取某一网页。在这个例子当中, 我们要把那公共时间线来进行获取标点符号:
r = requests.get('https://api.github.com/events')当下, 存在一个名为r的对象, 凭借这个对象, 能够获取一切我们所期望的信息。
容易操作的 API 表明所有 HTTP 请求种类都是一目了然的, 比如说, 你能够像这样去发送一个 HTTP POST 请求:
r = requests.post('http://httpbin.org/post', data = {'key':'value'})轻易, 是不是? 那另外的HTTP请求类别, 为PUT, , HEAD以及 又是咋办? 全都是同样的简便:
r = requests.put('http://httpbin.org/put', data = {'key':'value'}) r = requests.delete('http://httpbin.org/delete') r = requests.head('http://httpbin.org/get') r = requests.options('http://httpbin.org/get')传递参数
在我们发送请求之际, 常常得向服务端发送请求参数, 一般而言参数都是以键与值相对的那种形式放置到URL里头, 是跟于一个问号过后的。比如, /get?key=val。 准许你运用关键字参数, 借由一个字符串字典去提供这些参数。举个例子, 要是你想把key1=及key2=传递到 /get , 那么你能够采用像下面这样的代码: 。
payload = {'key1': 'value1', 'key2': 'value2'} r = requests.get("http://httpbin.org/get", params=payload) print(r.url) # 输出结果 http://httpbin.org/get?key1=value1&key2=value2通过打印输出该 URL,你能看到 URL 已被正确编码。
需留意, 字典之中, 那些值为 None 的键, 皆不会被增添至 URL 的查询字符串之内。
你还可以将一个列表作为值传入:
payload = {'key1': 'value1', 'key2': ['value2', 'value3']} r = requests.get("http://httpbin.org/get", params=payload) # 输出结果 http://httpbin.org/get?key1=value1&key2=value2&key2=value3响应内容
举个例子, 就比如说以请求百度首页为例子来讲在这种情况下, 我们能够凭借返回去读取服务器响应的内容来达成某些事情。
import requests r = requests.get('http://www.baidu.com') print(r.text) #返回(太多,只显示一部分)它能够自动进行解码, 针对来自服务器的内容来开展, 大多数字符集是可以被它无缝地予以解码的。
在请求被发出之后, 会依据HTTP头部针对响应的编码得出有凭借的推测。当你去访问r.text的时候, 会运用其所推测出的文本编码。你能够借助r.去获取所使用的编码:
r.encoding # 输出结果 'utf-8'并且能够使用 r. 属性来改变它:
r.encoding = 'ISO-8859-1'假设存在这样一种情况, 即要是你把编码进行了改变, 那么在每一次你去访问 r.text 的时候, 就都会去使用 r 的新值。
二进制响应内容
就非文本请求而言, 比如说那种图片请求, 你同样能够以字节这一形式去访问请求响应体。并且, 它还会自动地为你去解码gzip以及传输编码的响应数据。
比如, 凭借要求回报的二进制数据去构建一幅图片, 你能够运用像下面这样的代码:
import requests from PIL import Image from io import BytesIO r = requests.get('http://img.sccnn.com/bimg/326/203.jpg') print(r.content) bi = BytesIO(r.content) print(bi) i = Image.open(bi) print(i) # 输出结果 b'\xff\xd8\xff\xe0\x00\x10JFIF\x00\... <_io.BytesIO object at 0x1112fdbf8>JSON 响应内容
里头存在着一个被设立于内部的JSON解码器装置在里边, 它能够给予援手帮你去处理那与JSON有关的数据材料:
r = requests.get('https://api.github.com/events') print(r.json()) # 输出结果 [{u'repository': {u'open_issues': 0, u'url': 'https://github.com/...要是 JSON 解码遭遇失败这种情形, 那么 r.json() 便会抛出一个异常。
r = requests.get('https://www.baidu.com') print(r.json()) # 输出结果 json.decoder.JSONDecodeError: Expecting value: line 1 column 1 (char 0)要留意的是, 成功调用 r.json() 并不表明响应是成功的 , 有的服务器会在失败的响应里包含一个 JSON 对象 , 像是 HTTP 500 的错误细节 , 这种 JSON 会被解码返回 , 要检查请求是否成功 , 请使用 r.() 或者检查 r. 是否与你的期望一致 , 标点符号请确保。
原始响应内容
在极少的情形之下, 你或许会打算去获取源于服务器的原始套接字回应, 那么你能够去访问r.raw。在这个时候要保证在初始请求当中设置了 =True。具体而言你能够如此去做: 。
r = requests.get('https://api.github.com/events', stream=True) print(r.raw) print(r.raw.read(10)) # 输出结果 '\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\x03'设置请求头
要是你在开展爬取某一页面内容的行为之际, 发觉所获取的数据呈现为空的状态, 然而经由浏览器直接去访问URL却并无问题, 在这种时候极有可能是你被服务器认定为爬虫用户了, 该怎么办才好呢? 我们理应去模拟浏览器进行请求, 在这个时候你需要针对请求增添HTTP头部信息, 仅仅只需简单地把一个dict传递给参数便可以达成了。
例如,我们设置一下 User-Agent :
url = 'http://www.baidu.com' headers = {'User-Agent': 'myagent/2.21.0'} r = requests.get(url, headers=headers) print(r.request.headers) # 输出结果 {'User-Agent': 'myagent/2.21.0', 'Accept-Encoding': 'gzip, deflate', 'Accept': '*/*', 'Connection': 'keep-alive'}能够瞧见, 所请求的 User - Agent, 已然转变成为所设置的 /2.21.0 了。
复杂的 POST 请求
每当我们运用那种 POST 请求之际, 去打印一回 r.text 的话, 就会发觉每一回都会呈现出几个关键字: 。
{ "args": {}, "data": "", "files": {}, "form": {}, "headers": {}, "json": null, "origin": "221.232.172.222, 221.232.172.222", "url": "https://httpbin.org/post" }在POST的参数里头能够设置这些关键字, 其中, 和args先前我们已然讲过, 它们分别代表请求头以及参数信息, 是指请求的路由ip, url是我们所请求的url, 其馀几个我们是能够进行设置的, 接下来我们就要瞧瞧其他几个关键字如何展开设置。
设置data参数
要是你于POST请求之际打算提交表单, 同样仅仅只需简便地递送一个字典给data参数就行。你那个数据字典在发起请求之时会自行编码成为表单样式:
payload = {'key1': 'value1', 'key2': 'value2'} r = requests.post("http://httpbin.org/post", data=payload) print(r.text) # 输出结果 { ... "form": { "key1": "value1", "key2": "value2" }, ... }对于那 data 参数, 你同样能够去传入一个元组所构成的列表, 它就将会被自动地转换为一个列表。
payload = (('key1', 'value1'), ('key1', 'value2')) r = requests.post("http://httpbin.org/post", data=payload) print(r.text) # 输出结果 { ... "form": { "key1": [ "value1", "value2" ] }, ... }设置 json 参数
许可你运用json径直传送参数, 接着它便会被自行编码。
payload = {'some': 'data'} r = requests.post("http://httpbin.org/post", json=payload) print(r.text) # 输出结果 { "args": {}, "data": "{\"some\": \"data\"}", "files": {}, "form": {}, "headers": { "Accept": "*/*", "Accept-Encoding": "gzip, deflate", "Content-Length": "16", "Content-Type": "application/json", "Host": "httpbin.org", "User-Agent": "python-requests/2.21.0" }, "json": { "some": "data" }, "origin": "221.232.172.222, 221.232.172.222", "url": "https://httpbin.org/post" }留意, 在此处, 不但对json进行了赋值操作, 并且还自动给予data赋值, json内部的键值对也被自动编码到data里了。
设置文件参数
上传文件很简单:
files = {'file': open('test.txt', 'rb')} r = requests.post('http://httpbin.org/post', files=files) print(r.text) # 输出结果 { ... "files": { "file": "this is a file test" }, ... }你也可以增加一个参数,把字符串发送到上传的文件中,例如:
files = {'file': ('test.txt', 'some,data,to,send\nanother,row,to,send\n')} r = requests.post('http://httpbin.org/post', files=files) print(r.text) # 输出结果 { ... "files": { "file": "some,data,to,send\nanother,row,to,send\n" }, ... }响应状态码和响应头
我们能够从服务器回应的成果里面取得状态码以及响应头的资讯, 举例来说:
r = requests.get('http://httpbin.org/get') print(r.status_code) # 输出结果 200为方便引用,还附带了一个内置的状态码查询对象:
print(r.status_code == requests.codes.ok) # 输出结果 True我们还可以查看响应的响应头信息:
r = requests.get('http://httpbin.org/get') print(r.headers) # 输出结果 {'Access-Control-Allow-Credentials': 'true', 'Access-Control-Allow-Origin': '*', 'Content-Encoding': 'gzip', 'Content-Type': 'application/json', 'Date': 'Wed, 18 Sep 2019 12:22:06 GMT', 'Referrer-Policy': 'no-referrer-when-downgrade', 'Server': 'nginx', 'X-Content-Type-Options': 'nosniff', 'X-Frame-Options': 'DENY', 'X-XSS-Protection': '1; mode=block', 'Content-Length': '183', 'Connection': 'keep-alive'}要获取响应头的某个字段值,我们可以这样:
print(r.headers['Content-Encoding']) # 输出结果 gzip如果一个响应中包含了 ,那么我们可以利用 变量来拿到:
url = 'http://example.com/some/cookie/setting/url' r = requests.get(url) r.cookies['example_cookie_name'] # 输出结果 'example_cookie_value'以上所呈现出的程序, 仅仅只是属于样例范畴, 于运行该程序的情况下并不将会收获所得下文之反馈返回内容, 是需要包含着何种具体内容的响应才能够得以收获到的呢。
另外可以利用 变量来向服务器发送 信息:
cookies = dict(cookies_are='working') r = requests.get('http://httpbin.org/cookies', cookies=cookies) print(r.text) # 输出结果 { "cookies": { "cookies_are": "working" } }可以看到我们设置 参数后,返回中就包含了我们设置的信息。
为其设置不同的那些, 此所涉返回对象是这样一种情况, 它跟字典相仿具有那种适用性特质, 适宜于跨越域名以及跨越路径去运用的, 这就表明, 我们能够针对不一样的域名或者路径来进行相关设置的。你还能够将Jar传送至其中去呀:
jar = requests.cookies.RequestsCookieJar() #为路径/cookies设置cookie jar.set('tasty_cookie', 'yum', domain='httpbin.org', path='/cookies') #为路径/elsewhere设置cookie jar.set('gross_cookie', 'blech', domain='httpbin.org', path='/elsewhere') #请求路径为/cookies的URL url = 'http://httpbin.org/cookies' r = requests.get(url, cookies=jar) print(r.text) # 输出结果 { "cookies": { "tasty_cookie": "yum" } }重定向与请求历史
在默认情形之下, 除去 HEAD 请求之外, 会对所有重定向进行自动处理。
可以使用响应对象的 方法来追踪重定向。
它是一个对象的列表, 此对象列表依据从最老到最近的请求开展排序。
例如, 将所有的 HTTP 请求重定向到 HTTPS:
r = requests.get('http://github.com') print(r.url) print(r.status_code) print(r.history) # 输出结果 https://github.com/ 200 []要是你运用的电脑是Mac, 当运行这段代码时出现报错, 即“: reset by peer”, 那你就得对你系统进行升级, 具体办法自行去百度搜索关键词“mac 更新”, 在更新好后就不会再呈现报错的情况了。
我们还可以通过 参数禁用重定向处理:
r = requests.get('http://github.com', allow_redirects=False) print(r.status_code) print(r.history) # 输出结果 301 []超时
你能够借由进行设置, 把参数予以确定, 从而去告知, 在历经了借助该参数所设定的秒数时间过后, 停下用于等待回应所用的行为。
requests.get('http://github.com', timeout=0.001) # 输出结果 requests.exceptions.ConnectTimeout: HTTPConnectionPool(host='github.com', port=80): Max retries exceeded with url: / (Caused by ConnectTimeoutError(, 'Connection to github.com timed out. (connect timeout=0.001)'))这里因设置极短超时时间致使请求停下等待响应, 进而引发报错, 要注意, 这仅对连接过程起作用, 和响应体的下载并无关联, 并非是整个下载响应的时间限定, 而是倘若服务器在特定秒数内未作出应答, 便会引发一个异常。