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 相关文章推荐
python3.x上post发送json数据
Mar 04 Python
Python八大常见排序算法定义、实现及时间消耗效率分析
Apr 27 Python
python如何生成各种随机分布图
Aug 27 Python
python爬虫 execjs安装配置及使用
Jul 30 Python
使用coverage统计python web项目代码覆盖率的方法详解
Aug 05 Python
Pytorch中的variable, tensor与numpy相互转化的方法
Oct 10 Python
python使用pygame实现笑脸乒乓球弹珠球游戏
Nov 25 Python
django API 中接口的互相调用实例
Apr 01 Python
Django form表单与请求的生命周期步骤详解
Jun 07 Python
python中的yield from语法快速学习
Nov 06 Python
python 爬虫爬取京东ps4售卖情况
Dec 18 Python
看看如何用Python绘制小米新版天价logo
Apr 20 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
如何冲泡挂耳包咖啡?技巧是什么
2021/03/04 冲泡冲煮
用PHP实现小型站点广告管理(修正版)
2006/10/09 PHP
PHP查询网站的PR值
2013/10/30 PHP
PHP微信支付开发实例
2016/06/22 PHP
Python中使用django form表单验证的方法
2017/01/16 PHP
对laravel的session获取与存取方法详解
2019/10/08 PHP
硬盘浏览程序,保存成网页格式便可使用
2006/12/03 Javascript
JavaScript实现模仿桌面窗口的方法
2015/07/18 Javascript
jQuery实现可展开合拢的手风琴面板菜单
2015/09/15 Javascript
快速学习jQuery插件 Cookie插件使用方法
2015/12/01 Javascript
Bootstrap表格和栅格分页实例详解
2016/05/20 Javascript
Canvas实现放射线动画效果
2017/02/15 Javascript
JS解决IOS中拍照图片预览旋转90度BUG的问题
2017/09/13 Javascript
JS实现的ajax和同源策略(实例讲解)
2017/12/01 Javascript
Vue.js做select下拉列表的实例(ul-li标签仿select标签)
2018/03/02 Javascript
vue兄弟组件传递数据的实例
2018/09/06 Javascript
微信小程序如何修改本地缓存key中单个数据的详解
2019/04/26 Javascript
vue如何自动化打包测试环境和正式环境的dist/test文件
2019/06/06 Javascript
微信小程序实现日期格式化和倒计时
2020/11/01 Javascript
JavaScript实现表单验证功能
2020/12/09 Javascript
前端如何实现动画过渡效果
2021/02/05 Javascript
Python利用Nagios增加微信报警通知的功能
2016/02/18 Python
Python时间戳使用和相互转换详解
2017/12/11 Python
Python判断中文字符串是否相等的实例
2018/07/06 Python
VPS CENTOS 上配置python,mysql,nginx,uwsgi,django的方法详解
2019/07/01 Python
PyTorch实现更新部分网络,其他不更新
2019/12/31 Python
浅谈django channels 路由误导
2020/05/28 Python
python Yaml、Json、Dict之间的转化
2020/10/19 Python
python 自动识别并连接串口的实现
2021/01/19 Python
python 实现图片裁剪小工具
2021/02/02 Python
应聘护士自荐信
2013/10/21 职场文书
生物医学工程专业学生求职信范文分享
2013/12/14 职场文书
违反工作纪律检讨书
2014/02/15 职场文书
经济类毕业生求职信
2014/06/26 职场文书
人力资源管理专业求职信
2014/07/23 职场文书
2015年青年教师工作总结
2015/05/25 职场文书