学过关于urllib库的使用,你会发现它是很不方便的。而Requests工作起来会比urllib方便,Requests是Python实现的最简单易用的HTTP库,需要通过pip单独安装
开源地址:https://github.com/kennethreitz/requests
中文文档 API: http://docs.python-requests.org/zh_CN/latest/index.html
Requests 完全满足今日 web 的需求。
Keep-Alive & 连接池 国际化域名和 URL 带持久 Cookie 的会话 浏览器式的 SSL 认证 自动内容解码 基本/摘要式的身份认证 优雅的 key/value Cookie 自动解压 Unicode 响应体 HTTP(S) 代理支持 文件分块上传 流下载 连接超时 分块请求 支持
.netrc
import requests
#注意字典里值为 None 的键都不会被添加到 URL 的查询字符串里。
比urllib方便太多
# params 接收一个字典或者字符串的查询参数,字典类型自动转换为url编码,不需要urlencode() response = requests.get("http://www.baidu.com/s?", params=kw, headers = headers)
你也许经常想为 URL 的查询字符串(query string)传递某种数据。如果你是手工构建 URL,那么数据会以键/值对的形式置于 URL 中,跟在一个问号的后面。例如, httpbin.org/get?key=val
。 Requests 允许你使用 params
关键字参数,以一个字符串字典来提供这些参数。
# 查看响应头部字符编码 print(response.encoding) response.encoding = 'utf-8'
如果你改变了编码,每当你访问 response.text
,Request 都将会使用 response.encoding
的新值。你可能希望在使用特殊逻辑计算出文本的编码的情况下来修改编码。比如 HTTP 和 XML 自身可以指定编码。这样的话,你应该使用 response.content
来找到编码,然后设置response.encoding
为相应的编码。这样就能使用正确的编码解析 response.text
了。
在你需要的情况下,Requests 也可以使用定制的编码。如果你创建了自己的编码,并使用 codecs
模块进行注册,你就可以轻松地使用这个解码器名称作为 response.encoding
的值, 然后由 Requests 来为你处理编码。
>>> import requests >>> r = requests.get('https://github.com/timeline.json') >>> r.json() [{u'repository': {u'open_issues': 0, u'url': 'https://github.com/...
如果 JSON 解码失败, r.json()
就会抛出一个异常。例如,响应内容是 401 (Unauthorized),尝试访问 r.json()
将会抛出 ValueError: No JSON object could be decoded
异常。
需要注意的是,成功调用 r.json()
并**不**意味着响应的成功。有的服务器会在失败的响应中包含一个 JSON 对象(比如 HTTP 500 的错误细节)。这种 JSON 会被解码返回。要检查请求是否成功,请使用 r.raise_for_status()
或者检查 r.status_code
是否和你的期望相同。
import requests
r = requests.get('https://github.com/timeline.json')
r = requests.post("http://httpbin.org/post")
r = requests.put("http://httpbin.org/put")
r = requests.delete("http://httpbin.org/delete")
r = requests.head("http://httpbin.org/get")
r = requests.options("http://httpbin.org/get")
如果需要使用代理,你可以通过为任意请求方法提供 proxies
参数来配置单个请求:
import requests
# 根据协议类型,选择不同的代理
proxies = {
"http": "http://12.34.56.79:9527",
"https": "http://12.34.56.79:9527",
}
response = requests.get("http://www.baidu.com", proxies = proxies)
也可以通过本地环境变量 HTTP_PROXY
和 HTTPS_PROXY
来配置代理:
export HTTP_PROXY="http://12.34.56.79:9527" export HTTPS_PROXY="https://12.34.56.79:9527"
urllib这里的做法比较复杂,requests只需要一步:
import requests
# 如果代理需要使用HTTP Basic Auth,可以使用下面这种格式:
proxy = { "http": "mr_mao_hacker:sffqry9r@61.158.163.130:16816" }
response = requests.get("http://www.baidu.com", proxies = proxy)
print(response.text)
如果是Web客户端验证,需要添加 auth = (账户名, 密码)
import requests
auth=('test', '123456')
response = requests.get('http://127.0.0.10', auth = auth)
如果一个响应中包含了cookie,那么我们可以利用 cookies参数拿到:
import requests
response = requests.get('http://www.baidu.com')
#返回cookiejar对象
cookiejar = response.cookies
#转为字典
cookiedict = requests.utils.dict_from_cookiejar(cookiejar)
print(cookiejar)
print(cookiedict)
结果:
<RequestsCookieJar[<Cookie BDORZ=27315 for .baidu.com/>]> {'BDORZ': '27315'}
会话对象让你能够跨请求保持某些参数。它也会在同一个 Session 实例发出的所有请求之间保持 cookie, 期间使用 urllib3
的 connection pooling 功能。所以如果你向同一主机发送多个请求,底层的 TCP 连接将会被重用,从而带来显著的性能提升。 (参见 HTTP persistent connection).
会话对象具有主要的 Requests API 的所有方法。
我们来跨请求保持一些 cookie:
import requests
s = requests.Session()
s.get('http://httpbin.org/cookies/set/sessioncookie/123456789')
r = s.get("http://httpbin.org/cookies")
print(r.text)
{
"cookies": {
"sessioncookie": "123456789"
}
}
Requests也可以为HTTPS请求验证SSL证书:
import requests
response = requests.get("https://www.baidu.com/", verify=True)
# 也可以省略不写
# response = requests.get("https://www.baidu.com/")
print(r.text)
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)
解决方法:
import requests
import urllib3
urllib3.disable_warnings()
r = requests.get("https://www.12306.cn/mormhweb/", verify = False)
print(r.text)