学习一时爽,一直学习一直爽html
Hello,你们好,我是Connor,一个从无到有的技术小白。今天咱们继续来讲咱们的 Python 爬虫,上一次咱们说到了 urllib
与 urllib3
,不知道你们看了之后有何感想,今天咱们来继续聊聊 Python爬虫中的另外一个经常使用库——requests,相信你今天看了这篇文章之后必定有想要揍个人冲动。python
上一篇文章介绍了Python的网络请求库 urllib
和 urllib3
的使用方法,那么,做为一样是网络请求库的 Requests
,相较于 urllib
与 urllib3
,它有哪些优点呢?git
Requests 惟一的一个非转基因的 Python HTTP 库,人类能够安全享用。 警告:非专业使用其余 HTTP 库会致使危险的反作用,包括:安全缺陷症、冗余代码症、从新发明轮子症、啃文档症、抑郁、头疼、甚至死亡。 ——requests官方文档
Emmn.... 官方吐槽最为致命,从requests的话中,你就能够看得出它是多么的伟大了。程序员
requests
仍是少有的被官方推荐的库,在 urllib.request
的文档中,有这样的一句话来推荐 requests
:github
The Requests packageis recommended for a higher-level HTTP client interface.json
urllib
作为Python的标准库,由于历史缘由,使用的方式能够说是很是的麻烦而复杂的,并且官方文档也十分的简陋,经常须要去查看源码。与之相反的是,Requests
的使用方式很是的简单、直观、人性化,让程序员的精力彻底从库的使用中解放出来。浏览器
吹牛皮吹了这么久,那么requests
库究竟能够强大到什么地方呢?Twitter、Spotify、Microsoft、Amazon、Lyft、BuzzFeed、Reddit、NASA、Amazon、Google、Twilio、Mozilla、Heroku、PayPal、NPR、Obama for America、Transifex、Native Instruments、Washington Post、Twitter、SoundCloud、Kippt、Readability、以及若干不肯公开身份的联邦政府机构都在内部使用。安全
怎么样,是否是有了一种想要打个人冲动了?这么好的库竟然不早点拿出来讲,藏着掖着的...其实 requests
是很是少有的配备有官方中文文档的第三方库,若是有须要的话你也能够去看看他们的官方文档 点我走起>>>服务器
百度五分钟解决问题,群里吹牛逼俩小时,哈哈哈,貌似今天你百度也要跟着吹牛两小时了,下面咱们说点正经了,看看requests
到底应该怎么使用吧:cookie
若是你想使用request访问一个页面的话,那么你能够直接这样:
In [1]: import requests
In [2]: resp = requests.get('https://www.baidu.com')
In [3]: resp.status_code
Out[3]: 200
In [4]: resp.encoding
Out[4]: 'ISO-8859-1'
In [5]: resp.headers['Date']
Out[5]: 'Mon, 07 Jan 2019 07:30:15 GMT'
复制代码
能够看到,不管是发起请求仍是响应处理,都是很是直观明了的。requests
目前能够知足全部的请求需求,因此相较 urllib
与 urllib3
而言,你们仍是更加喜欢使用 requests
库来发起访问。
requests
的安装方式与全部的第三方库的安装方式都是相同的,你能够直接用 pip 进行安装
pip install requests
复制代码
requests
的请求再也不像urllib
同样须要去构造各类Request、opener和handler,使用requests
构造的方法,并在其中传入须要的参数便可。
在 reqeuest
模块中,每一种method方法都有对应的封装好的函数供你使用,好比说,进行GET请求的时候,你能够直接使用 get()
方法:
In [1]: import requests
In [2]: resp = requests.get('https://www.baidu.com')
复制代码
而当你须要进行POST请求的时候,你能够直接使用封装好了的 post()
方法来进行访问:
In [3]: resp = requests.post('https://www.baidu.com',
data = {'hello': 'world'})
复制代码
其它的请求方式也都有相对应的请求方法来进行请求,以下:
In [4]: resp = requests.put('http://httpbin.org/put', data = {'key':'value'})
In [5]: resp = requests.delete('http://httpbin.org/delete')
In [6]: resp = requests.head('http://httpbin.org/get')
In [7]: resp = requests.options('http://httpbin.org/get')
复制代码
虽然上述的几种方法并不经常使用,可是 requests
官方依旧很人性化的将它们都封装了进去。
传递URL参数的时候不再用使用 urllib
中的方法来将URL拼接起来了,它和 urllib3
的方式一致,直接将要拼接的 URL 构形成字典,传递给 params参数便可,和 urllib3
中的 request
方法中的 field
属性一致:
In [1]: import requests
In [2]: params = {'searchtype': '1', 'bookname': 'Detroit'}
In [3]: resp = requests.get('https://httpbin.org/get', params=params)
In [4]: resp.url
Out[4]: 'https://httpbin.org/get?searchtype=1&bookname=Detroit'
复制代码
能够清晰的看到,request
自动帮咱们把 params
参数拼接到了一块儿。固然,有的时候咱们也会遇到同名不一样值的参数,可是python语法中并不支持键名的重复,这个时候咱们能够把属性名相同的参数变成一个列表,request会自动的帮咱们把它们拼接到一块儿:
In [1]: import requests
In [2]: params = {'name': 'Connor', 'others': ['abc', 'def']}
In [3]: resp = requests.get('https://www.httpbin.org/get', params=params)
In [4]: resp.url
Out[4]: 'https://www.httpbin.org/get?name=Connor&others=abc&others=def'
复制代码
毫无疑问,requests
也可以设置 headers
参数,这是章口就莱的事,下面咱们来看看如何设置 headers
:
import requests
datas = {'name': 'Connor', 'age': '22', 'height': '166'}
headers = {'User-Agent': 'ABCDE'}
resp = requests.post('https://www.httpbin.org/post', headers=headers, data=datas)
print(resp.json()['headers'])
复制代码
运行以后的结果以下:
{'Accept': '*/*', 'Accept-Encoding': 'gzip, deflate', 'Connection': 'close', 'Content-Length': '29', 'Content-Type': 'application/x-www-form-urlencoded', 'Host': 'www.httpbin.org', 'User-Agent': 'ABCDE'}
复制代码
能够明显的看到,咱们的 User-Agent
属性已经变成了以前设定的 ABCDE,仍是很是简单的
reqeusts
还能够帮咱们构建cookie,咱们不用再建立CookieJar对象了,直接将你的 Cookie传递给Cookies参数便可:
In [1]: import requests
In [2]: url = 'https://www.httpbin.org/cookies'
In [3]: cook = {'leijun': 'Are you OK?'}
In [4]: resp = requests.get(url, cookies=cook)
In [5]: resp.text
Out[5]: '{\n "cookies": {\n "leijun": "Are you OK?"\n }\n}\n'
复制代码
requests
连cookie都帮咱们构建了,固然也少不了代理的构建,当咱们须要使用代理的时候须要把构造的字典传递给 proxies
参数便可
import requests
url = 'https://www.httpbin.org/ip'
datas = {'name': 'Connor', 'age': '22', 'height': '166'}
headers = {'User-Agent': 'ABCDE'}
proxy = {'http': 'http://110.52.235.90:9999', 'https': 'https://110.52.235.90:9999'}
resp1 = requests.get(url)
resp2 = requests.get(url, proxies=proxy)
print(resp1.text, resp2.text)
复制代码
运行以后的结果以下:
{"origin": "221.192.178.130"}
{"origin": "110.52.235.90"}
复制代码
再网络请求中,咱们经常会遇到状态码是3开头的重定向问题,在 requests
中默认是开启重定向的,即当咱们遇到重定向的时候,reqeusts
会自动帮咱们继续访问,你也能够手动关闭重定向:
In [1]: import requests
In [2]: url = 'http://www.jianshu.com'
In [3]: resp = requests.get(url, allow_redirects=False)
In [4]: resp.status_code
Out[4]: 301
复制代码
有些时候,当咱们使用了抓包工具的时候,因为抓包工具提供的证书不是受信任的数字证书颁发机构颁发的,因此会致使证书验证失败,这时咱们应该关闭证书验证。
在请求的时候,咱们能够关闭证书验证,只须要将 verify
属性设置为 False
便可:
In [1]: import requests
In [2]: resp = requests.get('https://www.baidu.com', verify=False)
d:\software\python\python\lib\site-packages\urllib3\connectionpool.py:847: 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)
复制代码
这个时候你会发现,关闭验证后会有一个烦人的847警告,你可使用如下方式来关闭警告:
from requests.packages.urllib3.exceptions import InsecureRequestWarning
# 禁用安全请求警告
requests.packages.urllib3.disable_warnings(InsecureRequestWarning)
复制代码
当咱们访问一个网站的时候,若是访问时间过久,或者响应时间太长,可能对咱们的效率有很大的影响,这个时候咱们能够设置超时时间,放弃一些数据来提高爬虫的效率。你只须要为其设置timeout
参数便可:
In [1]: import requests
In [2]: requests.get('http://github.com', timeout=0.001)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
requests.exceptions.Timeout: HTTPConnectionPool(host='github.com', port=80): Request timed out. (timeout=0.001)
复制代码
经过 requests
发起请求获得的对象是 Resopnse
对象,经过这个对象咱们能够方便的获取响应的内容。
在上一式咱们讲述 urllib
与 urllib3
的时候,咱们获取到的内容是二进制格式的,这个时候须要咱们本身手动的 decode()
将二进制的bytes数据转换成咱们能够读懂的字符串数据。可是在 requests
中,它的 text
属性会主动的经过可能的方式帮咱们解码:
In [1]: import requests
In [2]: url = 'https://www.httpbin.org/get'
In [3]: resp = requests.get(url)
In [4]: resp.text
Out[4]: '{\n "args": {}, \n "headers": {\n "Accept": "*/*", \n "Accept-Encoding": "gzip, deflate", \n "Connection": "close", \n "Host": "www.httpbin.org", \n "User-Agent": "python-requests/2.21.0"\n }, \n "origin": "221.192.178.130", \n "url": "https://www.httpbin.org/get"\n}\n'
复制代码
requests
会主动的帮咱们进行解码,它会经过响应的报头来猜想网页的编码是什么,而后根据猜想的编码来解码网页的内容。大部分的网页他都可以正确的解码,但也有解码不正确的时候,若是发现解码不正确了,咱们就须要本身来手动的指定解码的编码格式:
import requests
url = 'http://www.quanshuwang.com/'
resp = requests.get(url)
resp.encoding = 'GBK'
print(resp.text)
复制代码
在这里我给你们推荐一个其余的python自带的库,这个库也是在猜想网页的编码格式,可是这个库的准确率更高一些吧。何况咱们每次指定解码格式就要求咱们去看网页的编码格式。像新浪微博这样的网站,它在无序可视化的页面上使用的是 GBK 编码格式,在须要可视的页面上的编码格式是 UTF-8,咱们不但愿每次访问都手动的去更改它的编码格式,这个时候就用下面这种方法:
这个时候,咱们可使用 chardet
中的 detect
方法:
import requests
import chardet
url = 'https://www.httpbin.org/get'
resp = requests.get(url)
resp.encoding = chardet.detect(resp.content)
print(resp.text)
复制代码
若是你须要得到网页的原始二进制数据的时候,那么使用 content
属性便可:
In [1]: import requests
In [2]: url = 'https://www.httpbin.org/get'
In [3]: resp = requests.get(url)
In [4]: resp.content
Out[4]: b'{\n "args": {}, \n "headers": {\n "Accept": "*/*", \n "Accept-Encoding": "gzip, deflate", \n "Connection": "close", \n "Host": "www.httpbin.org", \n "User-Agent": "python-requests/2.21.0"\n }, \n "origin": "221.192.178.130", \n "url": "https://www.httpbin.org/get"\n}\n'
复制代码
若是咱们访问以后得到的数据是JSON格式的,那么咱们可使用json()
方法,直接获取转换成字典格式的数据:
In [1]: import requests
In [2]: url = 'https://www.httpbin.org/get'
In [3]: resp = requests.get(url)
In [4]: resp.json()
Out[4]:
{'args': {},
'headers': {'Accept': '*/*',
'Accept-Encoding': 'gzip, deflate',
'Connection': 'close',
'Host': 'www.httpbin.org',
'User-Agent': 'python-requests/2.21.0'},
'origin': '221.192.178.130',
'url': 'https://www.httpbin.org/get'}
复制代码
有时候咱们过于频繁的访问一个网址以后,或者某些网站对访问速度有限制的话,那咱们应该判断如下响应的状态码,而后再判断是否须要数据的提取。你能够经过 status_code
属性来获取响应的状态码:
In [1]: import requests
In [2]: url = 'https://www.httpbin.org/get'
In [3]: resp = requests.get(url)
In [4]: resp.status_code
Out[4]: 200
复制代码
当咱们进行了访问以后,若是你想查看该网页的响应报头,那么你能够经过 headers
属性来查看你的响应报头:
In [1]: import requests
In [2]: url = 'https://www.httpbin.org/get'
In [3]: resp = requests.get(url)
In [4]: resp.headers
Out[4]: {'Connection': 'keep-alive', 'Server': 'gunicorn/19.9.0', 'Date': 'Mon, 07 Jan 2019 11:36:04 GMT', 'Content-Type': 'application/json', 'Content-Length': '277', 'Access-Control-Allow-Origin': '*', 'Access-Control-Allow-Credentials': 'true', 'Via': '1.1 vegur'}
复制代码
你能够经过响应对象的 cookies
属性来获取服务器返回的 cookies
:
In [1]: import requests
In [2]: url = 'https://www.httpbin.org/get'
In [3]: resp = requests.get(url)
In [4]: resp.cookies
Out[4]: <RequestsCookieJar[]>
复制代码
返回的cookies是一个CookieJar对象,若是你想使用这个cookie,你仍是须要构建CookieJar对象。cookies
在后续的内容里我会专门抽出一节课来说这个的,这里咱们掠过,只须要知道经过 cookie
属性能够获取从网页上访问的 cookies
便可。
你也能够经过 url
属性来查看响应的url,你能够经过这种方式来判断网页是否进行了重定向等各种操做:
In [1]: import requests
In [2]: url = 'http://www.jianshu.com'
In [3]: resp = requests.get(url)
In [4]: resp.url
Out[4]: 'https://www.jianshu.com'
复制代码
在 requests
中,实现了 Session
会话功能,当咱们使用 Session
的时候,可以像浏览器同样,在没有关闭浏览器的时候,保持访问的状态,这个功能经常用于登录以后,能够避免咱们一次又一次的传递 cookies。session
其实很是的简单易用,它和 requests
对象几乎没有任何的差异,requests
的经常使用方法在 session
这里依旧适用。下面咱们举一个简单的例子:
import requests
url = 'https://www.httpbin.org/cookies'
session = requests.session()
resp = sesssion.get('https://www.httpbin.org/get')
print(resp.text)
复制代码
运行结果以下:
{"args": {}, "headers": {"Accept": "*/*", "Accept-Encoding": "gzip, deflate", "Connection": "close", "Cookie": "eare=https://www.httpbin.org", "Host": "www.httpbin.org", "User-Agent": "python-requests/2.20.0"}, "origin": "221.192.178.173", "url": "https://www.httpbin.org/get"}
复制代码
从上面的运行结果中咱们能够看到,session
操做起来仍是很是容易上手的,它的方法和requests
的用法几乎是彻底一致的。固然 session
也有本身更为独有的功能,下面咱们一块儿来看看它还有哪些其它的功能:
既然以前咱们说 session
是一个能够大大提升效率的工具,能够保持一些数据,不用频繁的重复传参,那咱们来试试看:
import requests
url = 'https://www.httpbin.org/cookies'
session = requests.session()
cook = {'eare': 'https://www.httpbin.org'}
resp = session.get(url, cookies=cook)
print(resp.text)
resp = session.get('https://www.httpbin.org/get')
print(resp.text)
复制代码
运行后的结果以下:
{"cookies": {"eare": "https://www.httpbin.org"}}
{"args": {}, "headers": {"Accept": "*/*", "Accept-Encoding": "gzip, deflate", "Connection": "close", "Host": "www.httpbin.org", "User-Agent": "python-requests/2.20.0"}, "origin": "221.192.178.173", "url":"https://www.httpbin.org/get"}
复制代码
经过上面的结果咱们会发现,第二次访问的时候并无维持第一次访问时设置的 session
啊,这是为何呢?难道是session的 doman
有问题?不是的,经过单次访问传参的方式来添加参数是不会对下一次访问起做用的,这个时候咱们须要使用一个方法 session.args.updata()
:
import requests
url = 'https://www.httpbin.org/cookies'
session = requests.session()
cook = {'eare': 'https://www.httpbin.org'}
session.cookies.update(cook)
resp = session.get(url)
print(resp.text)
resp = session.get('https://www.httpbin.org/get')
print(resp.text)
复制代码
此次咱们再来看运行结果:
{"cookies": {"eare": "https://www.httpbin.org"}}
{"args": {}, "headers": {"Accept": "*/*", "Accept-Encoding": "gzip, deflate", "Connection": "close", "Cookie": "eare=https://www.httpbin.org", "Host": "www.httpbin.org", "User-Agent": "python-requests/2.20.0"}, "origin": "221.192.178.173", "url": "https://www.httpbin.org/get"}
复制代码
这一次咱们明显的发现了第二次访问的时候带上了第一次设置的 cookie
参数,这样设置的话咱们以后的每次访问都无需再次传参了。固然,前提是在同一个域名下的访问。关于 cookie
的做用域的问题,我在以前的文章:Python 爬虫十六式 - 第一式:HTTP协议 >>> 中已经写到过了,若是看不懂的话请参照该文章。
在上面的内容中,有一点尤其须要注意: session.args.updata()
并不指实际的方法,这只是一类参数的统称,我的的命名习惯,若有错误,欢迎指出! session.args.updata()
包括以下的几种参数:
名称 | 做用 |
---|---|
headers | 设置session的请求头参数 |
cookies | 设置session的cookies |
params | 设置session的url拼接参数 |
proxies | 设置session的proxy代理 |
session
固然也为咱们提供了批量管理验证的方法,这与 requests
中的管理方式几乎相同,但和 session
的其它参数的管理相比又有所不一样。session.verify 是一个属性,它是一个 Boolean
型的变量,你只须要将它设置为 False
便可关闭 session
对象的全部证书验证:
import requests
url = 'https://www.httpbin.org/user-agent'
session = requests.session()
head = {'User-Agent': 'ABCDE'}
session.verify = False
session.headers.update(head)
resp = session.get(url)
print(resp.text)
复制代码
运行结果以下:
py:847: 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)
{"user-agent": "ABCDE"}
复制代码
嗯,又看到了烦人的 847报错,想要关闭它的话查看本文第2.3.7节证书验证,里面有如何关闭证书验证警告的方法,点我直达 >>>
好啦,到这里咱们就说完 requests
的使用了,不知道你学到了多少东西,可是依旧但愿这些东西对你有帮助,最后仍是那句话送给你们:
学习一时爽, 一直学习一直爽!
我是一个从无到有的技术小白,Connor,咱们下期再见!
Python 爬虫十六式 - 第一式:HTTP协议 >>>
Python 爬虫十六式 - 第二式:urllib 与 urllib3 >>>
Python 爬虫十六式 - 第四式:使用Xpath提取网页内容 >>>
Python 爬虫十六式 - 第五式:BeautifulSoup,美味的汤 >>>
Python 爬虫十六式 - 第六式:JQuery的假兄弟-pyquery >>>
Python 爬虫十六式 - 第七式:正则的艺术 >>>
Python 爬虫十六式 - 第八式:实例解析-全书网 >>>