来源 | 经授权转自 Crossin的编程教室(ID:crossincode)
一个月被下载6亿多发,github 5万多star,什么项目的数据这么炸?


说起python第三方库,你最先想到的是哪家?数据分析的pandas?图像处理的pillow?还是用Django来做Web开发?没错,它们都很牛叉,但这个库的下载量竟然比它们都要大。

关注编程教室,学习编程知识,今天我们就来讲讲这个号称“最人性化”的HTTP库--requests

怎么个人性化法?

假如你要通过一个天气API接口获取某个城市的气温变化,用requests来写,仅仅需要这样两行代码:
import requests
r = requests.get('http://api.tangdouz.com/tq.php?dz=南京')
print(r.text)
而其他一些常见的网络请求操作,如:
提交带参数的post请求

修改网页的编码(encoding)

解码json数据

自定义请求头(headers)

添加cookie

设定请求等待时长(timeout)

诸如此类的操作都可以通过requests提供的属性或方法,在一两行代码内轻松拿下。
而想要得到这些,你所要做的仅仅是通过 pip install 安装一下,以及通过官方文档了解模块的使用方法。
你可能要说了,这些难道Python内置的模块不能实现?诶,那倒不至于,只是……没那么方便。
比如,我现在要请求一个:
限制了浏览器类型、需要提交一组参数的POST接口,而返回结果是编码为UTF8的JSON格式数据,另外还做了gzip压缩。

如果用Python默认的库来做,每一步都需要手动来处理,代码比较繁琐。
from urllib.request import Request, urlopen
from urllib.parse import urlencode
import gzip
import json
headers = {'User-Agent': 'Chrome'}
data = {'username': 'test_user', 'password': '123456'}
url = 'https://api.example.com/login'
data_encoded = urlencode(data).encode('utf-8')
req = Request(url, data=data_encoded, headers=headers, method='POST')
response = urlopen(req)
recv_data = response.read()
if response.getheader("Content-Encoding") == "gzip":
recv_data = gzip.decompress(recv_data)
json_string = recv_data.decode('utf-8')
result = json.loads(json_string)
print(result)
response.close()
换成requests,则只需要在post函数中提供字典类型的headers和data参数,就完成了对请求头和数据的设定。而至于返回结果的gzip解压和utf8解码,都会自动帮你搞定。假如编码没有被识别,也只要一个赋值就可以成功运行。
最后再用json函数把结果解析成直接可用的字典类型。开发者省去了很多琐碎的工作,代码量大大减轻。
import requests
headers = {'User-Agent': 'Chrome'}
data = {'username': 'test_user', 'password': '123456'}
url = 'https://api.example.com/login'
response = requests.post(url, headers=headers, data=data)
response.encoding = 'utf-8'
result = response.json()
print(result)
更不要说,如果想要实现登录后的状态保持,原本的内置库要用 http.cookiejar 和 urllib.request 配合实现,写出来的代码是这样的:
from urllib.request import build_opener, HTTPCookieProcessor, Request
from urllib.parse import urlencode
import http.cookiejar
login_url = 'https://example.com/login'
login_data = {'username': 'test_user', 'password': '123456'}
headers = {'User-Agent': 'Chrome'}
data_encoded = urlencode(login_data).encode('utf-8')
cookie_jar = http.cookiejar.CookieJar()
opener = build_opener(HTTPCookieProcessor(cookie_jar))
login_request = Request(login_url, data=data_encoded, headers=headers, method='POST')
login_response = opener.open(login_request)
protected_url = 'https://example.com/profile'
profile_request = Request(protected_url, headers=headers, method='GET')
profile_response = opener.open(profile_request)
print(profile_response.read().decode('utf-8'))
login_response.close()
profile_response.close()
而requests就简单多了,直接增加一个Session对象,就能在几乎不改动之前代码的情况下,实现登录状态的保持。
import requests
login_url = 'https://example.com/login'
login_data = {'username': 'test_user', 'password': '123456'}
headers = {'User-Agent': 'Chrome'}
session = requests.Session()
login_response = session.post(login_url, data=login_data, headers=headers)
protected_url = 'https://example.com/profile'
profile_response = session.get(protected_url, headers=headers)
print(profile_response.text)
两种写法的差别,对比非常明显。一旦你有过requests的经验,就打开了网络请求的新世界,再也不想用内置的urllib来实现。
就连各家大厂的Python项目,网络请求也常常用requests来解决。毕竟这么好用的模块,相信谁都不会拒绝。
广泛的使用率也让requests始终霸榜在PyPI排行的前列。

而如此强大的类库,最初仅仅是一个程序员的个人项目。2011年某个下午,一个叫做 Kenneth 的小伙子因为无法忍受Python内置的urllib库,决定施展一下他的开发技术,写一个真正人性化的HTTP请求库,没想到竟写成了Python生态的重要支柱。
说到这个Kenneth,也是技术圈里充满话题的人物。在软件开发之外,他还热衷于音乐和摄影艺术。从他不同时期的照片就能看出,他本人的故事也一定很丰富。 (参见:这个男人让你的爬虫开发效率提升8倍)

除了requests,另一个很受欢迎的Python虚拟环境管理工具 Pipenv,也是由他发布。凭借这些项目,他一度是Github上获得star最多的Python用户。

不过如今,他已将大部分项目移交给了Python开源社区管理维护。每一个Python开发者都有机会向项目贡献自己的技术。
如果你是Python初学者,还没进行过第三方模块的学习,那不妨从requests做起,它上手简单文档清晰,是开发爬虫和API请求必学的神器。
如果你已经入门了Python,想要进一步提升自己的编程能力,也可以把requests项目当做进阶学习的案例,阅读源代码、学习代码风格和程序结构的设计,甚至提交代码改进项目中的问题,为开源项目贡献一份力。