python爬虫入门教程--优雅的HTTP库requests(二)


Posted in Python onMay 25, 2017

前言

urllib、urllib2、urllib3、httplib、httplib2 都是和 HTTP 相关的 Python 模块,看名字就觉得很反人类,更糟糕的是这些模块在 Python2 与 Python3 中有很大的差异,如果业务代码要同时兼容 2 和 3,写起来会让人崩溃。

好在,还有一个非常惊艳的 HTTP 库叫 requests,它是 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'

请求首部

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

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

请求体

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)

响应内容

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 完美支持代理。这里我用的是本地 ShadowSocks 的代理,(socks协议的代理要这样安装 pip install requests[socks]

import requests

proxies = {
 'http': 'socks5://127.0.0.1:1080',
 'https': 'socks5://127.0.0.1:1080',
}

requests.get('https://foofish.net', proxies=proxies, timeout=5)

超时设置

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

在python爬虫入门教程--快速理解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 相关文章推荐
python实现的希尔排序算法实例
Jul 01 Python
Tensorflow环境搭建的方法步骤
Feb 07 Python
python学习——内置函数、数据结构、标准库的技巧(推荐)
Apr 18 Python
python调用动态链接库的基本过程详解
Jun 19 Python
python自定义时钟类、定时任务类
Feb 22 Python
python将字母转化为数字实例方法
Oct 04 Python
简单了解为什么python函数后有多个括号
Dec 19 Python
Python猴子补丁知识点总结
Jan 05 Python
计算pytorch标准化(Normalize)所需要数据集的均值和方差实例
Jan 15 Python
python去除删除数据中\u0000\u0001等unicode字符串的代码
Mar 06 Python
pytorch中 gpu与gpu、gpu与cpu 在load时相互转化操作
May 25 Python
Python OpenCV超详细讲解调整大小与图像操作的实现
Apr 02 Python
Python操作使用MySQL数据库的实例代码
May 25 #Python
python爬虫入门教程--快速理解HTTP协议(一)
May 25 #Python
用生成器来改写直接返回列表的函数方法
May 25 #Python
Python随机读取文件实现实例
May 25 #Python
利用Anaconda完美解决Python 2与python 3的共存问题
May 25 #Python
Python实现的简单dns查询功能示例
May 24 #Python
Python向日志输出中添加上下文信息
May 24 #Python
You might like
PHP开发大型项目的一点经验
2006/10/09 PHP
使用php批量删除数据库下所有前缀为prefix_的表
2014/06/09 PHP
PHP获取路径和目录的方法总结【必看篇】
2017/03/04 PHP
php获取手机端的号码以及ip地址实例代码
2018/09/12 PHP
javascript Xml增删改查(IE下)操作实现代码
2009/01/30 Javascript
jQuery EasyUI API 中文文档 - Draggable 可拖拽
2011/09/29 Javascript
有关javascript的性能优化 (repaint和reflow)
2013/04/12 Javascript
JS window对象的top、parent、opener含义介绍
2013/12/03 Javascript
JQuery表格拖动调整列宽效果(自己动手写的)
2014/09/01 Javascript
如何使用HTML5地理位置定位功能
2015/04/27 Javascript
jQuery预加载图片常用方法
2015/06/15 Javascript
js简单实现Select互换数据的方法
2015/08/17 Javascript
js实现的Easy Tabs选项卡用法实例
2015/09/06 Javascript
js闭包引起的事件注册问题介绍
2016/03/29 Javascript
jQuery 获取屏幕高度、宽度的简单实现案例
2016/05/17 Javascript
jQuery Easyui加载表格出错时在表格中间显示自定义的提示内容
2016/12/08 Javascript
js实现数字递增特效【仿支付宝我的财富】
2017/05/05 Javascript
Angular中$state.go页面跳转并传递参数的方法
2017/05/09 Javascript
JQuery.dataTables表格插件添加跳转到指定页
2017/06/09 jQuery
JavaScript操作文件_动力节点Java学院整理
2017/06/30 Javascript
详解Javascript 中的 class、构造函数、工厂函数
2017/12/20 Javascript
解决webpack无法通过IP地址访问localhost的问题
2018/02/22 Javascript
python选择排序算法实例总结
2015/07/01 Python
Python打造出适合自己的定制化Eclipse IDE
2016/03/02 Python
python3.x提取中文的正则表达式示例代码
2019/07/23 Python
python GUI库图形界面开发之PyQt5中QMainWindow, QWidget以及QDialog的区别和选择
2020/02/26 Python
详解python内置模块urllib
2020/09/09 Python
canvas绘制圆角头像的实现方法
2019/01/17 HTML / CSS
app内嵌H5 webview 本地缓存问题的解决
2020/10/19 HTML / CSS
思想汇报格式
2014/01/05 职场文书
有兼职工作经历的简历自我评价
2014/03/07 职场文书
优质服务演讲稿
2014/05/14 职场文书
2015年社区科普工作总结
2015/05/13 职场文书
关于Javascript闭包与应用的详解
2021/04/22 Javascript
MySQL sql_mode的使用详解
2021/05/08 MySQL
使用pandas生成/读取csv文件的方法实例
2021/07/09 Python