在系列文章的第一篇中介绍了 HTTP 协议,Python 提供了很多模块来基于 HTTP 协议的网络编程,urllib、urllib2、urllib3、httplib、httplib2,都是和 HTTP 相关的模块,看名字觉得很反人类,更糟糕的是这些模块在 Python2 与 Python3 中有很大的差异,如果业务代码要同时兼容 2 和 3,写起来会让人崩溃。

幸运地是,繁荣的 Python 社区给开发者带来了一个非常惊艳的 HTTP 库 requests,一个真正给人用的HTTP库。它是 GitHUb 关注数最多的 Python 项目之一,requests 的作者是 Kenneth Reitz 大神。

requests 实现了 HTTP 协议中绝大部分功能,它提供的功能包括 Keep-Alive、连接池、Cookie持久化、内容自动解压、HTTP代理、SSL认证、连接超时、Session等很多特性,最重要的是它同时兼容 python2 和 python3。

快速入门

requests 的安装可以直接使用 pip 方法:pip install requests

>>> import requests
# GET 请求
>>> response = requests.get("https://foofish.net")

返回的时 Response 对象,Response 对象是 对 HTTP 协议中服务端返回给浏览器的响应数据的封装,响应的中的主要元素包括:状态码、原因短语、响应首部、响应体等等,这些属性都封装在Response 对象中。

# 状态码
>>> response.status_code
200 # 原因短语
>>> response.reason
'OK' # 响应首部
>>> for name,value in response.headers.items():
... print("%s:%s" % (name, value))
...
Content-Encoding:gzip
Server:nginx/1.10.2
Date:Thu, 06 Apr 2017 16:28:01 GMT # 响应内容
>>> response.content '<html><body>此处省略一万字...</body></html>

requests 除了支持 GET 请求外,还支持 HTTP 规范中的其它所有方法,包括 POST、PUT、DELTET、HEADT、OPTIONS方法。

>>> r = requests.post('http://httpbin.org/post', data = {'key':'value'})
>>> 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都带有很长一串参数,我们称这些参数为URL的查询参数,用"?"附加在URL链接后面,多个参数之间用"&"隔开,比如:http://fav.foofish.net/?p=4&s=20 ,现在你可以用字典来构建查询参数:

>>> args = {"p": 4, "s": 20}
>>> response = requests.get("http://fav.foofish.net", params = args)
>>> response.url
'http://fav.foofish.net/?p=4&s=2'

构建请求首部 Headers

requests 可以很简单地指定请求首部字段 Headers,比如有时要指定 User-Agent 伪装成浏览器发送请求,以此来蒙骗服务器。直接传递一个字典对象给参数 headers 即可。

>>> r = requests.get(url, headers={'user-agent': 'Mozilla/5.0'})

构建 POST 请求数据

requests 可以非常灵活地构建 POST 请求需要的数据,如果服务器要求发送的数据是表单数据,则可以指定关键字参数 data,如果要求传递 json 格式字符串参数,则可以使用json关键字参数,参数的值都可以字典的形式传过去。

作为表单数据传输给服务器

>>> payload = {'key1': 'value1', 'key2': 'value2'}
>>> r = requests.post("http://httpbin.org/post", data=payload)

作为 json 格式的字符串格式传输给服务器

>>> import json
>>> url = 'http://httpbin.org/post'
>>> payload = {'some': 'data'}
>>> r = requests.post(url, json=payload)

Response中的响应体

HTTP返回的响应消息中很重要的一部分内容是响应体,响应体在 requests 中处理非常灵活,与响应体相关的属性有:content、text、json()。

content 是 byte 类型,适合直接将内容保存到文件系统或者传输到网络中

>>> r = requests.get("https://pic1.zhimg.com/v2-2e92ebadb4a967829dcd7d05908ccab0_b.jpg")
>>> type(r.content)
<class 'bytes'>
# 另存为 test.jpg
>>> with open("test.jpg", "wb") as f:
... f.write(r.content)

text 是 str 类型,比如一个普通的 HTML 页面,需要对文本进一步分析时,使用 text。

>>> r = requests.get("https://foofish.net/understand-http.html")
>>> type(r.text)
<class 'str'>
>>> re.compile('xxx').findall(r.text)

如果使用第三方开放平台或者API接口爬取数据时,返回的内容是json格式的数据时,那么可以直接使用json()方法返回一个经过json.loads()处理后的对象。

>>> r = requests.get('https://www.v2ex.com/api/topics/hot.json')
>>> r.json()
[{'id': 352833, 'title': '在长沙,父母同住...

代理设置

当爬虫频繁地对服务器进行抓取内容时,很容易被服务器屏蔽掉,因此要想继续顺利的进行爬取数据,使用代理是明智的选择。如果你想爬取墙外的数据,同样设置代理可以解决问题,requests 完美支持代理。

import requests

proxies = {
'http': 'http://10.10.1.10:3128',
'https': 'http://10.10.1.10:1080',
} requests.get('http://example.org', proxies=proxies)

超时设置

requests 发送请求时,默认请求下线程一直阻塞,直到有响应返回才处理后面的逻辑。如果遇到服务器没有响应的情况时,问题就变得很严重了,它将导致整个应用程序一直处于阻塞状态而没法处理其他请求。

>>> import requests
>>> r = requests.get("http://www.google.coma")
...一直阻塞中

正确的方式的是给每个请求显示地指定一个超时时间。

>>> r = requests.get("http://www.google.coma", timeout=5)
5秒后报错
Traceback (most recent call last):
socket.timeout: timed out

Session

爬虫入门系列(一):快速理解HTTP协议中介绍过HTTP协议是一中无状态的协议,为了维持客户端与服务器之间的通信状态,使用 Cookie 技术使之保持双方的通信状态。

有些网页是需要登录才能进行爬虫操作的,而登录的原理就是浏览器首次通过用户名密码登录之后,服务器给客户端发送一个随机的Cookie,下次浏览器请求其它页面时,就把刚才的 cookie 随着请求一起发送给服务器,这样服务器就知道该用户已经是登录用户。

import requests
# 构建会话
session = requests.Session()
# 登录url
session.post(login_url, data={username, password})
# 登录后才能访问的url
r = session.get(home_url)
session.close()

构建一个session会话之后,客户端第一次发起请求登录账户,服务器自动把cookie信息保存在session对象中,发起第二次请求时requests 自动把session中的cookie信息发送给服务器,使之保持通信状态。

项目实战

最后是一个实战项目,如何用 requests 实现知乎自动登录并给用户发私信,我会在下一篇文章中进行讲解,关注公众号 ‘Python之禅’。

延伸阅读:

同步发表博客:https://foofish.net/http-requests.html
公众号:Python之禅 (id:VTtalk),分享 Python 等技术干货

爬虫入门系列(二):优雅的HTTP库requests的更多相关文章

  1. 爬虫入门系列(三):用 requests 构建知乎 API

    爬虫入门系列目录: 爬虫入门系列(一):快速理解HTTP协议 爬虫入门系列(二):优雅的HTTP库requests 爬虫入门系列(三):用 requests 构建知乎 API 在爬虫系列文章 优雅的H ...

  2. Python爬虫入门(二)之Requests库

    Python爬虫入门(二)之Requests库 我是照着小白教程做的,所以该篇是更小白教程hhhhhhhh 一.Requests库的简介 Requests 唯一的一个非转基因的 Python HTTP ...

  3. scrapy爬虫学习系列二:scrapy简单爬虫样例学习

    系列文章列表: scrapy爬虫学习系列一:scrapy爬虫环境的准备:      http://www.cnblogs.com/zhaojiedi1992/p/zhaojiedi_python_00 ...

  4. Maven入门系列(二)--设置中央仓库的方法

    原文地址:http://www.codeweblog.com/maven入门系列-二-设置中央仓库的方法/ Maven仓库放在我的文档里好吗?当然不好,重装一次电脑,意味着一切jar都要重新下载和发布 ...

  5. mybatis入门系列二之输入与输出参数

    mybatis入门系列二之详解输入与输出参数   基础知识   mybatis规定mapp.xml中每一个SQL语句形式上只能有一个@parameterType和一个@resultType 1. 返回 ...

  6. C语言高速入门系列(二)

    C语言高速入门系列(二) -----转载请注明出处coder-pig 本节引言: 在前面一节中我们对C语言进行了初步的了解,学会了使用IDE进行代码的编写,编译执行! 在这一节中我们会对C语言的基本的 ...

  7. Scrapy爬虫入门系列3 将抓取到的数据存入数据库与验证数据有效性

    抓取到的item 会被发送到Item Pipeline进行处理 Item Pipeline常用于 cleansing HTML data validating scraped data (checki ...

  8. C# 互操作性入门系列(二):使用平台调用调用Win32 函数

    好文章搬用工模式启动ing ..... { 文章中已经包含了原文链接 就不再次粘贴了 言明 改文章是一个系列,但只收录了2篇,原因是 够用了 } --------------------------- ...

  9. [转]C# 互操作性入门系列(二):使用平台调用调用Win32 函数

    传送门 C#互操作系列文章: C# 互操作性入门系列(一):C#中互操作性介绍 C# 互操作性入门系列(二):使用平台调用调用Win32 函数 C# 互操作性入门系列(三):平台调用中的数据封送处理 ...

随机推荐

  1. SqlService性能检测和优化工具

    工具概要 如果你的数据库应用系统中,存在有大量表,视图,索引,触发器,函数,存储过程,sql语句等等,又性能低下,而苦逼的你又要对其优化,那么你该怎么办?哥教你,首先你要知道问题出在哪里?如果想知道问 ...

  2. 【Unity编程】Unity中的欧拉旋转

    欧拉角的定义 在写这篇博客之前,我搜索了网上很多关于欧拉角的定义,发现大部分引用自维基百科的定义,我这里也引述一下: 维基百科定义 莱昂哈德·欧拉用欧拉角来描述刚体在三维欧几里得空间的取向.对于任何参 ...

  3. Java面试09|多线程

    1.假如有Thread1.Thread2.Thread3.Thread4四条线程分别统计C.D.E.F四个盘的大小,所有线程都统计完毕交给Thread5线程去做汇总,应当如何实现? 把相互独立的计算任 ...

  4. OpenvSwitch Port Mirror in OpenStack Neutron

    前言 最近使用搭建了一个基于VXLAN的OpenStack 环境,发现要去dump ovs interfaces的包其实还是蛮麻烦的, 经过多番努力,找到了如下的在openstack下网络环境的一些t ...

  5. burpsuite+sqlmap跨登录验证SQL注入

    (我操作的系统是kali linux) 1.利用burpsuite代理设置拦截浏览器请求(具体操作步骤可参考:http://www.cnblogs.com/hito/p/4495432.html) 2 ...

  6. android 中判断WiFi是否可用的可靠方法 ,android 是否联网

    http://alex-yang-xiansoftware-com.iteye.com/blog/619841 在一些程序中,需要从网上下载数据,或者通过其他方式对网络产生流量,当wifi不可用时应该 ...

  7. iOS网络编程笔记——GCDAsyncSocket使用

    CocoaAsyncSocket为Mac和iOS提供了易于使用且强大的异步通信库. 简单的Socket通信包括了建连.断开连接.发送socket业务请求.重连这四个基本功能. 1.建立连接:GCDAs ...

  8. FastCGI超过活动超时时间

    线上环境:PHP5.4 and IIS 打开IIS管理器,找到FastCGI,打开后编辑选项 活动超时默认为70(秒) 请求超时默认为90(秒) 可根据项目需求来更改这两项的值

  9. UT源码 005

    NextDate函数问题 NextDate函数说明一种复杂的关系,即输入变量之间逻辑关系的复杂性 NextDate函数包含三个变量month.day和year,函数的输出为输入日期后一天的日期. 要求 ...

  10. Chapter 4. Working with Key/Value Pairs

    Chapter4 working with key/value pairs key/values pairs键值对是Spark中非常常见的一种数据类型(type),RDD有时经常操作键值对数据类型.第 ...