上一篇博客中,我们了解了urllib的基本用法,但是它还是存在很多缺陷,比如处理网页验证和Cookies时,需要写通过类来实例化对象比较麻烦。为了更加方便地实现这些操作,就有了更为强大的库requests,对于它来说Cookies、登录验证、代理设置等操作都容易很多。

文章目录

  • 1.基本用法
  • get请求
  • 小实例
    • 1.文本数据爬取
    • 2.二进制数据爬取
  • 5.响应
  • 6.文件上传
  • 7.Cookies
  • 8.会话维持
  • 9.SSL证书验证
  • 10.代理设置
  • 超时设置

1.基本用法

它如何简单我下面举个例子你们可以看看:

import requests
response = requests.get('http://www.baidu.com/')
print(response.text)


短短几行也就把百度首页的源代码获取下来了,是不是很简单,这是一个很小的部分而已。我们还可以看获取的网页状态码等一些其他信息。

print(response.status_code)
print(type(response))
print(r.cookies)
print(type(r.text))

最终得到的结果:

200
<class 'requests.models.Response'>
<RequestsCookieJar[]>
<class 'str'>

我们可看到状态码是正常的,然后返回的文本信息也是字符串类型的。也可以查看请求的Response的类型。
requests使用get()方法完成了GET请求,这倒不算什么,更方便在与请求请求,比如POST,PUT,DELETE等请求,下面我们可以看看POST请求。

response = requests.post('http://www.iqianyue.com/mypost')
print(response.text)

返回的结果:

<html>
<head>
<title>Post Test Page</title>
</head>
<body>
<form action="" method="post">
name:<input name="name" type="text" /><br>
passwd:<input name="pass" type="text" /><br>
<input name="" type="submit" value="submit" />
<br />
</body>
</html>

是不是很简单,其实这是一小点而已,post(),put(),delete()这三个函数就能直接实现对上面三种方式的请求。

get请求

HTTP中最常见的请求之一就是GET请求,下面首先来详细了解一下利用requests构建GET请求的方法。直接用request.get()就可以了。上面我也举过例子了。

那么,对于GET请求,如果要附加额外的信息,一般怎样添加呢?比如现在想添加两个参数,其中name是germey,age是22。要构造这个请求链接,是不是要直接写成:

r = requests.get('http://httpbin.org/get?name=germey&age=22')

这样看起来很不人性化,而且构造的网址灵活性差。一般情况下,这种信息数据会用字典来存储。我们可以这样来构造:

import requests
data = {'name': 'germey','age': 22
}
r = requests.get("http://httpbin.org/get", params=data)
print(r.text)

最终返回的结果是:

{"args": {"age": "22", "name": "germey"}, "headers": {"Accept": "*/*", "Accept-Encoding": "gzip, deflate", "Host": "httpbin.org", "User-Agent": "python-requests/2.18.4"}, "origin": "113.57.74.32, 113.57.74.32", "url": "https://httpbin.org/get?name=germey&age=22"
}

通过运行结果可以看到url构造成我们想要的形式了。http://httpbin.org/get?age=22&name=germey
另外,网页的返回类型实际上是str类型,但是它很特殊,是JSON格式的。所以,如果想直接解析返回结果,得到一个字典格式的话,可以直接调用json()方法。

import requests
r = requests.get("http://httpbin.org/get")
print(type(r.text))
print(r.json())
print(type(r.json()))

运行结果是这样的:

<class 'str'>
{'headers': {'Accept-Encoding': 'gzip, deflate', 'Accept': '*/*', 'Host': 'httpbin.org', 'User-Agent': 'python-requests/2.10.0'}, 'url': 'http://httpbin.org/get', 'args': {}, 'origin': '182.33.248.131'}
<class 'dict'>

但前提是返回结果是json()格式,如果不是这种格式直接解析的话会出现问题。
下面我们来写一两个简单的爬取让大家看看request如何进行get请求爬取并解析。

小实例

1.文本数据爬取

比如我们以知乎的一个页面为例https://www.zhihu.com/explore爬取下面的问题

import requests
from  lxml  import  etreeheaders = {'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/52.0.2743.116 Safari/537.36'
}
r = requests.get("https://www.zhihu.com/explore", headers=headers)
selector =etree.HTML(r.text)
title_list = selector.xpath('//div[@class="ExploreRoundtableCard-questionItem"]/a/text()')
print(title_list)

lxml 是一个解析库,后面我会专门单独来讲,通过上面这简单的几行代码,我就能完成基础的爬取,基本成功的提取了所有问题的内容,返回的结果是:

['信号频域和时域的关系是怎样的?','什么是信号?','信号与系统这门课程有何价值?','为什么机器人研究了几十年,还是给人感觉没有太大进展?','这种不考试,以娱乐为主的机器人教育对于中小学生及幼儿的意义何在?','人形机器人的研究的意义是什么?','公司招聘时号称弹性工作制,入职后部门领导却要求打卡上班,应该怎么办?','对于工作 5 年以上的职场人来说,有哪些比工资低更危险的事?','在你的行业里,有哪些看似「不职业」的行为其实是「非常职业」的表现?','申请国外 PhD 的时候如何与教授套磁?','科研工作者有哪些「新手常见错误」?','如何成为一个不油腻的科研工作者?']
2.二进制数据爬取

在上面的例子中,我们抓取的是知乎的一个页面,实际上它返回的是一个HTML文档。如果想抓去图片、音频、视频等文件,应该怎么办呢?图片、音频、视频这些文件本质上都是由二进制码组成的,由于有特定的保存格式和对应的解析方式,我们才可以看到这些形形色色的多媒体。所以,想要抓取它们,就要拿到它们的二进制码。
举个例子https://github.com/favicon.ico这个是github的一个图标,当我们直接请求,然后打印返回的结果会乱码,因为我们直接打印会将图片直接转化为字符串肯定会乱码,我们下面这样做就没问题,而且在当前路径下回生成一个图标样式的文件。

import requests
r = requests.get("https://github.com/favicon.ico")
with open('favicon.ico', 'wb') as f:f.write(r.content)

在我们上面请求中,第一个知乎中添加了headers,也就是请求头,我们需要在请求头中添加user-agent,不然很有可能请求不到。也可以在headers这个参数中添加任意的其他字段信息。

5.响应

在python请求中,我们要通过返回的状态码对响应结果进行分析,查看是出了什么问题,下面我列出所有的状态码大家可以看一下:

# 信息性状态码
100: ('continue',),
101: ('switching_protocols',),
102: ('processing',),
103: ('checkpoint',),
122: ('uri_too_long', 'request_uri_too_long'),# 成功状态码
200: ('ok', 'okay', 'all_ok', 'all_okay', 'all_good', '\\o/', '✓'),
201: ('created',),
202: ('accepted',),
203: ('non_authoritative_info', 'non_authoritative_information'),
204: ('no_content',),
205: ('reset_content', 'reset'),
206: ('partial_content', 'partial'),
207: ('multi_status', 'multiple_status', 'multi_stati', 'multiple_stati'),
208: ('already_reported',),
226: ('im_used',),# 重定向状态码
300: ('multiple_choices',),
301: ('moved_permanently', 'moved', '\\o-'),
302: ('found',),
303: ('see_other', 'other'),
304: ('not_modified',),
305: ('use_proxy',),
306: ('switch_proxy',),
307: ('temporary_redirect', 'temporary_moved', 'temporary'),
308: ('permanent_redirect','resume_incomplete', 'resume',), # These 2 to be removed in 3.0# 客户端错误状态码
400: ('bad_request', 'bad'),
401: ('unauthorized',),
402: ('payment_required', 'payment'),
403: ('forbidden',),
404: ('not_found', '-o-'),
405: ('method_not_allowed', 'not_allowed'),
406: ('not_acceptable',),
407: ('proxy_authentication_required', 'proxy_auth', 'proxy_authentication'),
408: ('request_timeout', 'timeout'),
409: ('conflict',),
410: ('gone',),
411: ('length_required',),
412: ('precondition_failed', 'precondition'),
413: ('request_entity_too_large',),
414: ('request_uri_too_large',),
415: ('unsupported_media_type', 'unsupported_media', 'media_type'),
416: ('requested_range_not_satisfiable', 'requested_range', 'range_not_satisfiable'),
417: ('expectation_failed',),
418: ('im_a_teapot', 'teapot', 'i_am_a_teapot'),
421: ('misdirected_request',),
422: ('unprocessable_entity', 'unprocessable'),
423: ('locked',),
424: ('failed_dependency', 'dependency'),
425: ('unordered_collection', 'unordered'),
426: ('upgrade_required', 'upgrade'),
428: ('precondition_required', 'precondition'),
429: ('too_many_requests', 'too_many'),
431: ('header_fields_too_large', 'fields_too_large'),
444: ('no_response', 'none'),
449: ('retry_with', 'retry'),
450: ('blocked_by_windows_parental_controls', 'parental_controls'),
451: ('unavailable_for_legal_reasons', 'legal_reasons'),
499: ('client_closed_request',),# 服务端错误状态码
500: ('internal_server_error', 'server_error', '/o\\', '✗'),
501: ('not_implemented',),
502: ('bad_gateway',),
503: ('service_unavailable', 'unavailable'),
504: ('gateway_timeout',),
505: ('http_version_not_supported', 'http_version'),
506: ('variant_also_negotiates',),
507: ('insufficient_storage',),
509: ('bandwidth_limit_exceeded', 'bandwidth'),
510: ('not_extended',),
511: ('network_authentication_required', 'network_auth', 'network_authentication')

6.文件上传

我们知道requests可以模拟浏览器提交一些数据,加入有的网站需要上传文件,我们也可以用它来实现:

import requests
files = {'file': open('favicon.ico', 'rb')}
r = requests.post("http://httpbin.org/post", files=files)
print(r.text)

返回的结果大家可以在自己电脑上看。

7.Cookies

前面我们使用urllib处理过Cookies,写法比较复杂,而有了requests,获取和设置Cookies只需一步即可完成。

import requests
r = requests.get("http://tieba.baidu.com/f?ie=utf-8&kw=%E6%B9%96%E5%8C%97%E7%BB%8F%E6%B5%8E%E5%AD%A6%E9%99%A2")
print(r.cookies)
for key, value in r.cookies.items():print(key + '=' + value)

运行结果如下:

<RequestsCookieJar[<Cookie BAIDUID=691FAAA9A1B2BCC389C3803DE3F3A7DE:FG=1 for .baidu.com/>, <Cookie TIEBA_USERTYPE=3fad14137434bb1707615468 for .tieba.baidu.com/>]>
BAIDUID=691FAAA9A1B2BCC389C3803DE3F3A7DE:FG=1
TIEBA_USERTYPE=3fad14137434bb1707615468

这里我们首先调用cookies属性即可成功得到Cookies,可以发现它是RequestCookieJar类型。然后用items()方法将其转化为元组组成的列表,遍历输出每一个Cookie的名称和值,实现Cookie的遍历解析。
当然我们也可以将自己登陆后的cookies来维持登录状态,下面还是用知乎为例

import requests
headers = {'Cookie': '_zap=fb088aab-4271-4702-9f79-a83cd3b241b1; _xsrf=21713a2f-9a52-4c69-b5a0-cbc42a04b641; d_c0="AIAi3k8pEhCPTtIPkdiPzE_HPvUWm1JHut0=|1568876696"; tgw_l7_route=4860b599c6644634a0abcd4d10d37251; capsion_ticket="2|1:0|10:1568881198|14:capsion_ticket|44:ZDAzNjlmNmE3NTBhNDQyNDllNjUwZTY2NjNhMzEzZGQ=|79ba5fb5fbee8187a4f17d962e1fc8e313ae9ce3e3574857ad7c23df7bf5c00d"; l_n_c=1; r_cap_id="MzY2MmE1OWQ1ZDkwNDU3MTg0OWFlYzA3NGE0YzQ1MTg=|1568881210|22639adc0478eb7daaf98a39b322fdde3c4b886a"; cap_id="ZmZjYTY2YTZiMzgyNDEwNjgxYWQzNzQxYzgwMmNjMzM=|1568881210|d0f484488bf9ff8393b986c989b0ad9431b781eb"; l_cap_id="NWY5YzgzZWRkOTNlNDJlNmEwZWE2NTQ5MGNkYzQ0YjE=|1568881210|c8fc82e6624979ff0aa88fdd0458a9023b19df2a"; n_c=1; z_c0=Mi4xNDU1cEJnQUFBQUFBZ0NMZVR5a1NFQmNBQUFCaEFsVk5RWWh3WGdCdEd1SzgyYTJCV0RCYTNTN3ZsSXRJSG9PRFVB|1568881217|0f2d335543b8478a74b018564a8d27b7bf914f3b; tst=r','Host': 'www.zhihu.com','User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2785.116 Safari/537.36',
}
r = requests.get('https://www.zhihu.com', headers=headers)
print(r.text)

这样我们就实现了用cookies保持登录状态,这里的cookies换成自己的试试:

8.会话维持

在requests中,如果直接利用get()或post()等方法的确可以做到模拟网页的请求,但是这实际上是相当于不同的会话,也就是说相当于你用了两个浏览器打开了不同的页面。
设想这样一个场景,第一个请求利用post()方法登录了某个网站,第二次想获取成功登录后的自己的个人信息,你又用了一次get()方法去请求个人信息页面。实际上,这相当于打开了两个浏览器,是两个完全不相关的会话,能成功获取个人信息吗?那当然不能。其实解决这个问题的主要方法就是维持同一个会话,也就是相当于打开一个新的浏览器选项卡而不是新开一个浏览器。但是我又不想每次设置cookies,那该怎么办呢?这时候就有了新的利器——Session对象。
这里我们请求了一个测试网址http://httpbin.org/cookies/set/number/123456789。请求这个网址时,可以设置一个cookie,名称叫作number,内容是123456789,随后又请求了http://httpbin.org/cookies,此网址可以获取当前的Cookies。

import requests
requests.get('http://httpbin.org/cookies/set/number/123456789')
r = requests.get('http://httpbin.org/cookies')
print(r.text)

我们希望获取到cookies,返回的结果:

{"cookies": {}
}

这并不行。我们再用Session试试看

import requestss = requests.Session()
s.get('http://httpbin.org/cookies/set/number/123456789')
r = s.get('http://httpbin.org/cookies')
print(r.text)

返回结果是:

{"cookies": {"number": "123456789"}
}

成功获取!这下能体会到同一个会话和不同会话的区别了吧!

所以,利用Session,可以做到模拟同一个会话而不用担心Cookies的问题。它通常用于模拟登录成功之后再进行下一步的操作。

Session在平常用得非常广泛,可以用于模拟在一个浏览器中打开同一站点的不同页面。

9.SSL证书验证

此外,requests还提供了证书验证的功能。当发送HTTP请求的时候,它会检查SSL证书,我们可以使用verify参数控制是否检查此证书。其实如果不加verify参数的话,默认是True,会自动验证。

前面我们提到过,12306的证书没有被官方CA机构信任,会出现证书验证错误的结果。我们现在访问它,都可以看到一个证书问题的页面。
我们需要修改它的verify参数就正常了。

import requestsresponse = requests.get('https://www.12306.cn', verify=False)
print(response.status_code)


但它会警告我们让我们给它指定证书,我们也可以忽略。我们也可以上传一个本地证书,我下面给出一个样例格式:

import requestsresponse = requests.get('https://www.12306.cn', cert=('/path/server.crt', '/path/key'))
print(response.status_code)

当然,上面的代码是演示实例,我们需要有crt和key文件,并且指定它们的路径。注意,本地私有证书的key必须是解密状态,加密状态的key是不支持的。后面有具体的例子我再来给大家讲解。

10.代理设置

对于某些网站,在测试的时候请求几次,能正常获取内容。但是一旦开始大规模爬取,对于大规模且频繁的请求,网站可能会弹出验证码,或者跳转到登录认证页面,更甚者可能会直接封禁客户端的IP,导致一定时间段内无法访问。

那么,为了防止这种情况发生,我们需要设置代理来解决这个问题,这就需要用到proxies参数。可以用这样的方式设置:

import requestsproxies = {"http": "http://10.10.1.10:3128","https": "http://10.10.1.10:1080",
}requests.get("https://www.taobao.com", proxies=proxies)

这一块内容我们后面具体实践用到我在详细讲解,而且现在大多用的是那个API付费接口的代理,嵌入比较简单技术性要求不是很高,大家了解就行啦。最后在和大家提下超时设置,前面urllib也讲过了,实际差不多。

超时设置

在本机网络状况不好或者服务器网络响应太慢甚至无响应时,我们可能会等待特别久的时间才可能收到响应,甚至到最后收不到响应而报错。为了防止服务器不能及时响应,应该设置一个超时时间,即超过了这个时间还没有得到响应,那就报错。这需要用到timeout参数。这个时间的计算是发出请求到服务器返回响应的时间。示例如下:

import requestsr = requests.get("https://www.taobao.com", timeout = 1)
print(r.status_code)

返回200表示请求正常。实际上,请求分为两个阶段,即连接(connect)和读取(read)。

上面设置的timeout将用作连接和读取这二者的timeout总和。

如果要分别指定,就可以传入一个元组:

r = requests.get('https://www.taobao.com', timeout=(5,11, 30))

如果想永久等待,可以直接将timeout设置为None,或者不设置直接留空,因为默认是None。这样的话,如果服务器还在运行,但是响应特别慢,那就慢慢等吧,它永远不会返回超时错误的。其用法如下:

r = requests.get('https://www.taobao.com', timeout=None)
#r = requests.get('https://www.taobao.com')

当我们把这些大致了解,基本的request库用法也差不多了,剩下如果还有什么问题可以去官网查看。

爬虫系列-request基本库的使用相关推荐

  1. python beautifulsoup库_Python爬虫系列:BeautifulSoup库详解

    点击上方蓝字关注"程序员Bob"呀~ 每个人的生命都是通向自我的征途,是对一条道路的尝试,是一条小径的悄然召唤.人们从来都无法以绝对的自我之相存在,每一个人都在努力变成绝对自我,有 ...

  2. 爬虫系列之----Requests库

    Requsets库是一个擅长处理复杂的HTTP请求,cookie,header(响应头和请求头)等内容的python第三方库. 接下来将根据Requests官网上面的guid进行指导学习.http:/ ...

  3. python3爬虫系列03之requests库:根据关键词自动爬取下载百度图片

    python3爬虫系列03之requests库:根据关键词自动爬取下载百度图片 1.前言 在上一篇文章urllib使用:根据关键词自动爬取下载百度图片 当中,我们已经分析过了百度图片的搜索URL的变化 ...

  4. Python 网络爬虫笔记1 -- Requests库

    Python 网络爬虫笔记1 – Requests库 Python 网络爬虫系列笔记是笔者在学习嵩天老师的<Python网络爬虫与信息提取>课程及笔者实践网络爬虫的笔记. 课程链接:Pyt ...

  5. 【OpenCV图像处理入门学习教程六】基于Python的网络爬虫与OpenCV扩展库中的人脸识别算法比较

    OpenCV图像处理入门学习教程系列,上一篇第五篇:基于背景差分法的视频目标运动侦测 一.网络爬虫简介(Python3) 网络爬虫,大家应该不陌生了.接下来援引一些Jack-Cui在专栏<Pyt ...

  6. 「Python爬虫系列讲解」十二、基于图片爬取的 Selenium 爬虫

    本专栏是以杨秀璋老师爬虫著作<Python网络数据爬取及分析「从入门到精通」>为主线.个人学习理解为主要内容,以学习笔记形式编写的. 本专栏不光是自己的一个学习分享,也希望能给您普及一些关 ...

  7. 「Python爬虫系列讲解」十四、基于开发者工具 Network 的数据抓包技术

    本专栏是以杨秀璋老师爬虫著作<Python网络数据爬取及分析「从入门到精通」>为主线.个人学习理解为主要内容,以学习笔记形式编写的. 本专栏不光是自己的一个学习分享,也希望能给您普及一些关 ...

  8. 「Python爬虫系列讲解」三、正则表达式爬虫之牛刀小试

    本专栏是以杨秀璋老师爬虫著作<Python网络数据爬取及分析「从入门到精通」>为主线.个人学习理解为主要内容,以学习笔记形式编写的. 本专栏不光是自己的一个学习分享,也希望能给您普及一些关 ...

  9. python 全栈开发,Day137(爬虫系列之第4章-scrapy框架)

    python 全栈开发,Day137(爬虫系列之第4章-scrapy框架) 一.scrapy框架简介 1. 介绍 Scrapy一个开源和协作的框架,其最初是为了页面抓取 (更确切来说, 网络抓取 )所 ...

最新文章

  1. “秒杀”谷歌!这个生物科研工具,可爬取全网中外文献
  2. LFCS 系列第二讲:如何安装和使用纯文本编辑器 vi/vim
  3. IDE to AHCI/RAID 蓝屏补丁
  4. python能处理图片吗_python 能处理图像?
  5. Go Web编程--应用数据库
  6. “不要害怕 RAID!”
  7. [转载] python中chr()和ord()函数的用法
  8. 以变制变——前端动态化代码保护方案探索
  9. 人工智能产品经理工作流程
  10. usaco3.4.3 Raucous Rockers
  11. python如何安装pdfminer_Python 3.6 中使用pdfminer解析pdf文件的实现
  12. php工具下载 脚本之家,php脚本编辑工具题目
  13. LVGL lv_msgbox消息对话框(22)
  14. 如何在office2016(word2016)中安装mathtype6.9及相关问题解决方案
  15. 免费申报!5G网络Awards参评企业征集,欢迎参与!
  16. SQL Server2012 学习之(一) :入门知识
  17. img标签元素随父div等比例缩放
  18. 插图设计正流行,10大理由告诉你如何靠它增强用户体验
  19. 地图集web项目_技术学习(二)_bootstrap分页的例子
  20. Android FrameWork Input触控事件处理流程 笔记

热门文章

  1. Js逆向教程-07方法栈
  2. 安装HDF5,查看HDF5文件
  3. 斯坦福李飞飞团队新作:刷榜视觉自监督
  4. Spring cloud 开发培训
  5. 【量化干货】用python搭建量化交易策略(附零基础学习资料)
  6. 爬虫之豆瓣的自动登陆
  7. 刷单、刷热度、刷数据,618火爆背后的另一面
  8. 安卓手机怎么设置充电提示音
  9. Qt 6中的Qt Network
  10. Vue 和微信小程序的区别、比较