社区所有版块导航
Python
python开源   Django   Python   DjangoApp   pycharm  
DATA
docker   Elasticsearch  
aigc
aigc   chatgpt  
WEB开发
linux   MongoDB   Redis   DATABASE   NGINX   其他Web框架   web工具   zookeeper   tornado   NoSql   Bootstrap   js   peewee   Git   bottle   IE   MQ   Jquery  
机器学习
机器学习算法  
Python88.com
反馈   公告   社区推广  
产品
短视频  
印度
印度  
Py学习  »  Python

Python爬虫十六式 - 第三式:Requests的用法

Connor_Zhang • 5 年前 • 4608 次点击  
阅读 21

Python爬虫十六式 - 第三式:Requests的用法

Requests: 让 HTTP 服务人类

学习一时爽,一直学习一直爽

  Hello,大家好,我是Connor,一个从无到有的技术小白。今天我们继续来说我们的 Python 爬虫,上一次我们说到了 urlliburllib3 ,不知道大家看了以后有何感想,今天我们来继续聊聊 Python爬虫中的另一个常用库——requests,相信你今天看了这篇文章以后一定有想要揍我的冲动。

1.request 的简介

  上一篇文章介绍了Python的网络请求库 urlliburllib3 的使用方法,那么,作为同样是网络请求库的 Requests ,相较于 urlliburllib3,它有哪些优势呢?

Requests 唯一的一个非转基因的 Python HTTP 库,人类可以安全享用。
警告:非专业使用其他 HTTP 库会导致危险的副作用,包括:安全缺陷症、冗余代码症、重新发明轮子症、啃文档症、抑郁、头疼、甚至死亡。
                                                               ——requests官方文档

  Emmn.... 官方吐槽最为致命,从requests的话中,你就可以看得出它是多么的伟大了。

  requests 还是少有的被官方推荐的库,在 urllib.request 的文档中,有这样的一句话来推荐 requests :

The Requests packageis recommended for a higher-level HTTP client interface.

  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 是非常少有的配备有官方中文文档的第三方库,如果有需要的话你也可以去看看他们的官方文档 点我走起>>>


2.requests 的使用

  百度五分钟解决问题,群里吹牛逼俩小时,哈哈哈,貌似今天你百度也要跟着吹牛两小时了,下面我们说点正经了,看看requests到底应该怎么使用吧:

2.1 requests 的简单使用

  如果你想使用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目前可以满足所有的请求需求,所以相较 urlliburllib3 而言,大家还是更加喜欢使用 requests 库来发起访问。


2.2 requests 的安装

  requests 的安装方式与所有的第三方库的安装方式都是相同的,你可以直接用 pip 进行安装

pip install requests
复制代码

2.3 requests 的使用

   requests的请求不再像urllib一样需要去构造各种Request、opener和handler,使用requests构造的方法,并在其中传入需要的参数即可。

2.3.1 发起请求

  在 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 官方依旧很人性化的将它们都封装了进去。


2.3.2 传递 URL 参数

  传递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'
复制代码

2.3.3 自定义headers

  毫无疑问,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,还是非常简单的


2.3.4 自定义Cookies

  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'
复制代码

2.3.5 设置代理

  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"}
复制代码

2.3.6 重定向

  再网络请求中,我们常常会遇到状态码是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
复制代码

2.3.7 证书验证

  有些时候,当我们使用了抓包工具的时候,由于抓包工具提供的证书不是受信任的数字证书颁发机构颁发的,所以会导致证书验证失败,这时我们应该关闭证书验证。

  在请求的时候,我们可以关闭证书验证,只需要将 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)
复制代码

2.3.8 设置超时

  当我们访问一个网站的时候,如果访问时间太久,或者响应时间太长,可能对我们的效率有很大的影响,这个时候我们可以设置超时时间,放弃一些数据来提升爬虫的效率。你只需要为其设置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)
复制代码

2.4 requests的响应

  通过 requests 发起请求得到的对象是 Resopnse 对象,通过这个对象我们可以方便的获取响应的内容。

2.4.1 响应内容

  在上一式我们讲述 urlliburllib3 的时候,我们获取到的内容是二进制格式的,这个时候需要我们自己手动的 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'}
复制代码

2.4.2 状态码

  有时候我们过于频繁的访问一个网址之后,或者某些网站对访问速度有限制的话,那我们应该判断以下响应的状态码,然后再判断是否需要数据的提取。你可以通过 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
复制代码

2.4.3 响应报头

  当我们进行了访问之后,如果你想查看该网页的响应报头,那么你可以通过 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'}
复制代码

2.4.4 服务器返回的cookies

  你可以通过响应对象的 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 即可。


2.4.5 url

  你也可以通过 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'
复制代码

2.5 Session对象

2.5.1 Session 的简单使用

  在 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 也有自己更为独有的功能,下面我们一起来看看它还有哪些其它的功能:


2.5.2 updata方法

  既然之前我们说 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代理

2.5.3 Session.verify

  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 >>>


今天看啥 - 高品质阅读平台
本文地址:http://www.jintiankansha.me/t/bfe8zvg08g
Python社区是高质量的Python/Django开发社区
本文地址:http://www.python88.com/topic/27641
 
4608 次点击