您当前的位置: 首页 > 

蔚1

暂无认证

  • 0浏览

    0关注

    4753博文

    0收益

  • 0浏览

    0点赞

    0打赏

    0留言

私信
关注
热门博文

入门首选,Requests 库的基本使用

蔚1 发布时间:2020-03-12 23:31:36 ,浏览量:0

上一课时我们了解了一些学习爬虫所需要的基本知识。从本课时开始,我们正式步入Python 爬虫的大门。

目录:

  1. 安装
  2. 实例引入
  3. 请求
  4. 响应
  5. 高级用法

你好,我是悦创。

上一课时我们了解了一些学习爬虫所需要的基本知识。从本课时开始,我们正式步入 Python 爬虫的大门。

学习爬虫,最基础的便是模拟浏览器向服务器发出请求,那么我们需要从什么地方做起呢?请求需要我们自己来构造吗?需要关心请求这个数据结构的实现吗?需要了解 HTTP、TCP、IP 层的网络传输通信吗?需要知道服务器的响应和应答原理吗?

可能你无从下手,不过不用担心,Python 的强大之处就是提供了功能齐全的类库来帮助我们完成这些请求。利用 Python 现有的库我们可以非常方便地实现网络请求的模拟,常见的库有 urllib、requests 等。

拿 requests 这个库来说,有了它,我们只需要关心请求的链接是什么,需要传的参数是什么,以及如何设置可选的参数就好了,不用深入到底层去了解它到底是怎样传输和通信的。有了它,两行代码就可以完成一个请求和响应的处理过程,非常方便地得到网页内容。

接下来,就让我们用 Python 的 requests 库开始我们的爬虫之旅吧。

1. 安装

首先,requests 库是 Python 的一个第三方库,不是自带的。所以我们需要额外安装。

在这之前需要你先安装好 Python3 环境,如 Python 3.6 版本,如若没有安装可以参考:https://www.aiyc.top/article/2020/3/12/63.html。

安装好 Python3 之后,我们使用 pip3 即可轻松地安装好 requests 库:

pip3 install requests

更详细的安装方式可以参考:https://www.aiyc.top/article/2020/3/12/64.html。

安装完成之后,我们就可以开始我们的网络爬虫之旅了。

2. 实例引入

用 Python 写爬虫的第一步就是模拟发起一个请求,把网页的源代码获取下来。

当我们在浏览器中输入一个 URL 并回车,实际上就是让浏览器帮我们发起一个 GET 类型的 HTTP 请求,浏览器得到源代码后,把它渲染出来就可以看到网页内容了。

那如果我们想用 requests 来获取源代码,应该怎么办呢?很简单,requests 这个库提供了一个 get 方法,我们调用这个方法,并传入对应的 URL 就能得到网页的源代码。

比如这里有一个示例网站:https://static1.scrape.cuiqingcai.com/,其内容如下:

微信图片_20200312134842.png

这个网站展示了一些电影数据,如果我们想要把这个网页里面的数据爬下来,比如获取各个电影的名称、上映时间等信息,然后把它存下来的话,该怎么做呢?

第一步当然就是获取它的网页源代码了。

我们可以用 requests 这个库轻松地完成这个过程,代码的写法是这样的:

import requestsresponse = requests.get('https://static1.scrape.cuiqingcai.com/')print(response.text)# 运行结果如下:          Scrape | Movie  
Scrape
。。。。。。。。。。。。

由于网页内容比较多,这里省略了大部分内容。

不过看运行结果,我们已经成功获取网页的 HTML 源代码,里面包含了电影的标题、类型、上映时间,等等。把网页源代码获取下来之后,下一步我们把想要的数据提取出来,数据的爬取就完成了。

Ps:

如果上面代码运行报错,则使用以下代码:

"""project = 'Code', file_name = '19', author = 'AI 悦创'time = '2020/3/12 13:51', product_name = PyCharm# code is far away from bugs with the god animal protecting    I love animals. They taste delicious."""import requestsheaders = {    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.116 Safari/537.36',}response = requests.get('https://static1.scrape.cuiqingcai.com/', headers = headers, verify = False)print(response.text)

这个实例的目的是让你体会一下 requests 这个库能帮我们实现什么功能。我们仅仅用 requests 的 get 方法就成功发起了一个 GET 请求,把网页源代码获取下来了,是不是很方便呢?

3. 请求

HTTP 中最常见的请求之一就是 GET 请求,下面我们来详细了解利用 requests 库构建 GET 请求的方法。

3.1 GET 请求

我们换一个示例网站,其 URL 为 http://httpbin.org/get,如果客户端发起的是 GET 请求的话,该网站会判断并返回相应的请求信息,包括 Headers、IP 等。

我们还是用相同的方法来发起一个 GET 请求,代码如下:

import requestsr = requests.get('http://httpbin.org/get')print(r.text)# 运行结果如下{  "args": {},   "headers": {    "Accept": "*/*",     "Accept-Encoding": "gzip, deflate",     "Host": "httpbin.org",     "User-Agent": "python-requests/2.23.0",     "X-Amzn-Trace-Id": "Root=1-5e69d0fd-ead51d58ee34258cf5b52088"  },   "origin": "121.205.195.39",   "url": "http://httpbin.org/get"}

可以发现,我们成功发起了 GET 请求,也通过这个网站的返回结果得到了请求所携带的信息,包括 Headers、URL、IP,等等。

对于 GET 请求,我们知道 URL 后面是可以跟上一些参数的,如果我们现在想添加两个参数,其中 name 是 aiyuechuang,age 是 21,URL 就可以写成如下内容:

http://httpbin.org/get?name=aiyuechuang&age=21

要构造这个请求链接,是不是要直接写成这样呢?

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

这样也可以,但如果这些参数还需要我们手动拼接,未免有点不人性化。

一般情况下,这种信息我们利用 params 这个参数就可以直接传递了,示例如下:

import requestsdata = {    'name': 'aiyuechuang',    'age': 21}r = requests.get('http://httpbin.org/get', params=data)print(r.text)

运行结果如下:

{  "args": {    "age": "21",     "name": "aiyuechuang"  },   "headers": {    "Accept": "*/*",     "Accept-Encoding": "gzip, deflate",     "Host": "httpbin.org",     "User-Agent": "python-requests/2.23.0",     "X-Amzn-Trace-Id": "Root=1-5e69d232-168ef4ba9aaa55081a69f58a"  },   "origin": "121.205.195.39",   "url": "http://httpbin.org/get?name=aiyuechuang&age=21"}

在这里我们把 URL 参数通过字典的形式传给 get 方法的 params 参数,通过返回信息我们可以判断,请求的链接自动被构造成了:http://httpbin.org/get?name=aiyuechuang&age=21,这样我们就不用再去自己构造 URL 了,非常方便。

另外,网页的返回类型实际上是 str 类型,但是它很特殊,是 JSON 格式的。所以,如果想直接解析返回结果,得到一个 JSON 格式的数据的话,可以直接调用 json 方法。

示例如下:

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

运行结果如下:

{'args': {}, 'headers': {'Accept': '*/*', 'Accept-Encoding': 'gzip, deflate', 'Host': 'httpbin.org', 'User-Agent': 'python-requests/2.23.0', 'X-Amzn-Trace-Id': 'Root=1-5e69d308-975ea1443607a0f8109133ac'}, 'origin': '121.205.195.39', 'url': 'http://httpbin.org/get'}

可以发现,调用 json 方法,就可以将返回结果是 JSON 格式的字符串转化为字典。

但需要注意的是,如果返回结果不是 JSON 格式,便会出现解析错误,抛出 json.decoder.JSONDecodeError 异常。

3.2 抓取网页

上面的请求链接返回的是 JSON 形式的字符串,那么如果请求普通的网页,则肯定能获得相应的内容了。下面以本课时最初的实例页面为例,我们再加上一点提取信息的逻辑,将代码完善成如下的样子:

import requests,reresponse = requests.get('https://static1.scrape.cuiqingcai.com/')pattern = re.compile('(.*?)', re.S)titles = re.findall(pattern, response.text)print(titles)

在这个例子中我们用到了最基础的正则表达式来匹配出所有的标题。关于正则表达式的相关内容,我们会在下一课时详细介绍,这里作为实例来配合讲解。当然,有些小伙伴比较喜欢看视频学习,可以关注公众号:AI 悦创,观看视频学习正则表达式。

运行结果如下:

['霸王别姬 - Farewell My Concubine', '这个杀手不太冷 - Léon', '肖申克的救赎 - The Shawshank Redemption', '泰坦尼克号 - Titanic', '罗马假日 - Roman Holiday', '唐伯虎点秋香 - Flirting Scholar', '乱世佳人 - Gone with the Wind', '喜剧之王 - The King of Comedy', '楚门的世界 - The Truman Show', '狮子王 - The Lion King']

我们发现,这里成功提取出了所有的电影标题。一个最基本的抓取和提取流程就完成了。

3.3 抓取二进制数据

在上面的例子中,我们抓取的是网站的一个页面,实际上它返回的是一个 HTML 文档。如果想抓取图片、音频、视频等文件,应该怎么办呢?

图片、音频、视频这些文件本质上都是由二进制码组成的,由于有特定的保存格式和对应的解析方式,我们才可以看到这些形形色色的多媒体。所以,想要抓取它们,就要拿到它们的二进制数据。

下面以 GitHub 的站点图标为例来看一下:

import requestsr = requests.get('https://github.com/favicon.ico')print(r.text)print(r.content)

这里抓取的内容是站点图标,也就是在浏览器每一个标签上显示的小图标,如图所示:

这里打印了 Response 对象的两个属性,一个是 text,另一个是 content。

运行结果如图所示,其中前两行是 r.text 的结果,最后一行是 r.content 的结果。

可以注意到,前者出现了乱码,后者结果前带有一个 b,这代表是 bytes 类型的数据。

由于图片是二进制数据,所以前者在打印时转化为 str 类型,也就是图片直接转化为字符串,这当然会出现乱码。

上面返回的结果我们并不能看懂,它实际上是图片的二进制数据,没关系,我们将刚才提取到的信息保存下来就好了,代码如下:

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

这里用了 open 方法,它的第一个参数是文件名称,第二个参数代表以二进制的形式打开,可以向文件里写入二进制数据。

上面代码使用了 with open 方法,可以关注公众号:AI 悦创,或者这个链接了解:https://mp.weixin.qq.com/s/ExNmraka-VFjKudfetDmXw

运行结束之后,可以发现在文件夹中出现了名为 favicon.ico 的图标,如图所示。

这样,我们就把二进制数据成功保存成一张图片了,这个小图标就被我们成功爬取下来了。

同样地,音频和视频文件我们也可以用这种方法获取。

3.4 添加 headers

我们知道,在发起一个 HTTP 请求的时候,会有一个请求头 Request Headers,那么这个怎么来设置呢?

很简单,我们使用 headers 参数就可以完成了。

在刚才的实例中,实际上我们是没有设置 Request Headers 信息的,如果不设置,某些网站会发现这不是一个正常的浏览器发起的请求,网站可能会返回异常的结果,导致网页抓取失败。

要添加 Headers 信息,比如我们这里想添加一个 User-Agent 字段,我们可以这么来写:

import requestsheaders = {    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.116 Safari/537.36',}response = requests.get('https://static1.scrape.cuiqingcai.com/', headers = headers)print(response.text)

当然,我们可以在 headers 这个参数中任意添加其他的字段信息。

3.5 POST 请求

前面我们了解了最基本的 GET 请求,另外一种比较常见的请求方式是 POST。使用 requests 实现 POST 请求同样非常简单,示例如下:

import requestsdata = {    'name': 'aiyuechuang',    'age': 21}r = requests.post('http://httpbin.org/post', data = data)print(r.text)

这里还是请求 http://httpbin.org/post,该网站可以判断如果请求是 POST 方式,就把相关请求信息返回。

运行结果如下:

{  "args": {},   "data": "",   "files": {},   "form": {    "age": "21",     "name": "aiyuechuang"  },   "headers": {    "Accept": "*/*",     "Accept-Encoding": "gzip, deflate",     "Content-Length": "23",     "Content-Type": "application/x-www-form-urlencoded",     "Host": "httpbin.org",     "User-Agent": "python-requests/2.23.0",     "X-Amzn-Trace-Id": "Root=1-5e69d87c-326b7dd9a7567430c6a5db1a"  },   "json": null,   "origin": "121.205.195.39",   "url": "http://httpbin.org/post"}

可以发现,我们成功获得了返回结果,其中 form 部分就是提交的数据,这就证明 POST 请求成功发送了。

4. 响应

发送请求后,得到的自然就是响应,即 Response。

在上面的实例中,我们使用 text 和 content 获取了响应的内容。此外,还有很多属性和方法可以用来获取其他信息,比如状态码、响应头、Cookies 等。示例如下:

import requestsr = requests.get('https://static1.scrape.cuiqingcai.com/')print(type(r.status_code), r.status_code)print(type(r.headers), r.headers)print(type(r.cookies), r.cookies)print(type(r.url), r.url)print(type(r.history), r.history)

这里分别打印输出 status_code 属性得到状态码,输出 headers 属性得到响应头,输出 cookies 属性得到 Cookies,输出 url 属性得到 URL,输出 history 属性得到请求历史。

运行结果如下:

 200 {'Server': 'nginx/1.17.8', 'Date': 'Thu, 12 Mar 2020 06:41:14 GMT', 'Content-Type': 'text/html; charset=utf-8', 'Transfer-Encoding': 'chunked', 'Connection': 'keep-alive', 'Vary': 'Accept-Encoding', 'X-Frame-Options': 'SAMEORIGIN', 'Strict-Transport-Security': 'max-age=15724800; includeSubDomains', 'Content-Encoding': 'gzip'}  https://static1.scrape.cuiqingcai.com/ []

可以看到,headers 和 cookies 这两个属性得到的结果分别是 CaseInsensitiveDict 和 RequestsCookieJar 类型。

在第一课时我们知道,状态码是用来表示响应状态的,比如返回 200 代表我们得到的响应是没问题的,上面的例子正好输出的结果也是 200,所以我们可以通过判断 Response 的状态码来确认是否爬取成功。

requests 还提供了一个内置的状态码查询对象 requests.codes,用法示例如下:

import requestsr = requests.get('https://static1.scrape.cuiqingcai.com/')exit() if not r.status_code == requests.codes.ok else print("Request Successfully")

这里通过比较返回码和内置的成功的返回码,来保证请求得到了正常响应,输出成功请求的消息,否则程序终止,这里我们用 requests.codes.ok 得到的是成功的状态码 200。

这样的话,我们就不用再在程序里面写状态码对应的数字了,用字符串表示状态码会显得更加直观。

当然,肯定不能只有 ok 这个条件码。

下面列出了返回码和相应的查询条件:

img

比如,如果想判断结果是不是 404 状态,可以用 requests.codes.not_found 来比对。

5. 高级用法

刚才,我们了解了 requests 的基本用法,如基本的 GET、POST 请求以及 Response 对象。当然 requests 能做到的不仅这些,它几乎可以帮我们完成 HTTP 的所有操作。

下面我们再来了解下 requests 的一些高级用法,如文件上传、Cookies 设置、代理设置等。

5.1 文件上传

我们知道 requests 可以模拟提交一些数据。假如有的网站需要上传文件,我们也可以用它来实现,示例如下:

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

在上一课时中我们保存了一个文件 favicon.ico,这次用它来模拟文件上传的过程。需要注意的是,favicon.ico 需要和当前脚本在同一目录下。如果有其他文件,当然也可以使用其他文件来上传,更改下代码即可。

运行结果如下:

C:\Users\clela\AppData\Local\Programs\Python\Python37\python.exe C:/Code/pycharm_daima/崔庆才爬虫课程代码/19.py{  "args": {},   "data": "",   "files": {    "file": "data:application/octet-stream;base64,AA。。。。。。。AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA="  },   "form": {},   "headers": {    "Accept": "*/*",     "Accept-Encoding": "gzip, deflate",     "Content-Length": "6665",     "Content-Type": "multipart/form-data; boundary=f75a946281574191df1894b0b91c6cab",     "Host": "httpbin.org",     "User-Agent": "python-requests/2.23.0",     "X-Amzn-Trace-Id": "Root=1-5e69db89-e9abbf9b5524ae10b7935271"  },   "json": null,   "origin": "121.205.195.39",   "url": "http://httpbin.org/post"}

以上省略部分内容,这个网站会返回响应,里面包含 files 这个字段,而 form 字段是空的,这证明文件上传部分会单独有一个 files 字段来标识。

5.2 Cookies

我们如果想用 requests 获取和设置 Cookies 也非常方便,只需一步即可完成。

我们先用一个实例看一下获取 Cookies 的过程:

import requestsr = requests.get('http://www.baidu.com')print(r.cookies)for key, value in r.cookies.items():    print(key + '=' + value)

运行结果如下:

BDORZ=27315

这里我们首先调用 cookies 属性即可成功得到 Cookies,可以发现它是 RequestCookieJar 类型。然后用 items 方法将其转化为元组组成的列表,遍历输出每一个 Cookie 的名称和值,实现 Cookie 的遍历解析。

当然,我们也可以直接用 Cookie 来维持登录状态,下面我们以 GitHub 为例来说明一下,首先我们登录 GitHub,然后将 Headers 中的 Cookie 内容复制下来,如图所示:

微信图片_20200312153301.png

这里可以替换成你自己的 Cookie,将其设置到 Headers 里面,然后发送请求,示例如下:

import requestsheaders = {    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.116 Safari/537.36',    'Cookie': '你自己的 Cookies',}r = requests.get('https://github.com/', headers = headers)print(r.text)

我们发现,结果中包含了登录后才能显示的结果,如图所示:

微信图片_20200312153301.png

可以看到这里包含了我的 GitHub 用户名信息,你如果尝试同样可以得到你的用户信息。

得到这样类似的结果,说明我们用 Cookies 成功模拟了登录状态,这样我们就能爬取登录之后才能看到的页面了。

当然,我们也可以通过 cookies 参数来设置 Cookies 的信息,这里我们可以构造一个 RequestsCookieJar 对象,然后把刚才复制的 Cookie 处理下并赋值,示例如下:

import requestscookies = '_octo=GH1.1.1671699943.1582013885; _ga=GA1.2.549010125.1582013921; _device_id=e7ea4c6f4dac6cbe21b3261c834fd9c0; user_session=vBp2c_KwnigYF5ciafGv9jDHhrse7crnT9RXqotPrVvw_EGi; __Host-user_session_same_site=vBp2c_KwnigYF5ciafGv9jDHhrse7crnT9RXqotPrVvw_EGi; logged_in=yes; dotcom_user=MinRiHuang; tz=Asia%2FShanghai; has_recent_activity=1; _gat=1; _gh_sess=loELl80sXFY844RXwi3lek7nUI6l2WygmggDaPmdFSPo1Tl2LzAyhmpu6Jmr2F81Urx0q0OFllL5y986SpV8px1diL1AUFK0EbPCWO9o%2BXuuw4EtYM3gicvKzQfp6I9WjLCOhm8I5iQB8ZwKWQRopOdl2sbl6erBfkOGD3kA8NVouZt0IzxLowje6mHRPkMG7NCTpBQDOObx%2BrrX%2BOQQyYPWc83Cu7qrFJ%2BHYVbYZVAmXMgNJyUGm0QZxfeGqFZYfWPwoRm7zmweViXs%2BvF1m9W0cGMdoR7%2FcrS3FxX2YLh3soEiR%2BSdtevUVSuXKZplyEVrdomtA2Awx%2Fw0YdQScFSEsX7vKggoSVKkJOEU4JSVIRQbB7bLpupvHMr%2FbWCOTWMX6cW87bDI0mwd%2FvaTaNeEskVxPVhLWdbXP15UiSBpTW3ttZkNmty217UjlEL%2BK0yDgsLdxGJLSJEH%2B%2FXCZxHMJzSYcDzKeha5orO85TSOK4i%2Bn7hvkaakjVg9FK4Mclee5mwdLQCxmPK%2Bu9ZDnzuPsIZKDN3oZy1U128q7UNe7Ix4h1Kuls3vNzTSUJDir8jhvfq18P5x2kDr4VmH3M4O5bGLIdGBO9WpoYiASJqeWDKcczwytZ4%2FigWLNMMxWtm8U1IV8oA5JNxOeT%2FEE%2B4z8mg95gi3YOK%2F0mLHeX6nJ0gTLBzdsXHyk4D1106eDL6ECeMoVGS0CuHcpw%2F%2BdS9Fhn5hyUDh9g6y%2Fi%2FaPad6mmemvTygOWHvDkgGKAEL%2F9Uer1oW0gO6hytSi8ZbGeNTvGQq45TG5id7rm%2BBa3GcVFl9eo0z0e2i%2FpULjjrD7oSYwn7Ne294HUe%2BZz0QQKQVDuRQXfzuSK3dKOPDinjdMi6kgGWeoOFUiBbzYhT0P0nUokxLMSjh9udfyyEnnyk8ULp3smLnN9oA73wnqiJCvF6%2FwQPcEgvLI%2B%2BUr5nVydgArMNNj9oOzYXpPAMWVVyjQ1YWB%2FTxP7EKcTYuSqgLnmO9WtvFljlfALroNqdItYfNueAIQlES5P6BrGahHe1cZc3uClq1kZOp93lzfoUiffJZ2XWFmUjmL%2F%2Bz7Y%2BKcS%2Fhpr4pxZtWYiCW6HhVdaMibKPW1EQ1VX3TvAjnSiYCV%2FOoEkg21qygCVA4wqc4C1b%2BqKB8ya8krN4jArGYx0jdIyHtFtfrtIT%2FCecfYHGWWWDrsvfU48G1iDw%2BvHhu3OR9Z6JJp5l9UX1Vv6%2BJMCVGPmQp0ee2i5AWubCHw%2B7LE%2FFnhqqd2x01spbnn24si2LjfchEeHsY87JWKNhFstSluAM32zSb0JdARsG2E2sPSNnSTxtBi8UXO7jz9wSUnLp1eNgxDm2h4ajx8DgG3MQto8dK%2BnC24pEO8RJHexw0yjAwYAElqILFekWSa5jla4qxK%2FzdSEalXt3hyos2KvxHK9xBn0iIXQ9wq3sjUXqNVGAAmTDhppTKOAu1HBpoNRea4ZRYQtgEr2yIAGT4OP0myJwDPBJlBj6M3ZUl0SWoOKT6LK22b%2FmaLW6ETiRf6AIwZvxHcxr6Ny7oU3fVOaL9F27BlVBhRYAjtA%3D%3D--bpux229I12NmQCjr--UTq4wduGF0moZDkYQeO%2BQw%3D%3D',jar = requests.cookies.RequestCookieJar()headers = {    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.116 Safari/537.36',}for  cookie in cookies.split(";"):    key, value  = cookie.split('=', 1)    jar.set(key, value)r = requests.get('https://github.com/', cookies = jar, headers = headers)print(r.text)

这里我们首先新建一个 RequestCookieJar 对象,然后将复制下来的 cookies 利用 split 方法分割,接着利用 set 方法设置好每个 Cookie 的 key 和 value,最后通过调用 requests 的 get 方法并传递给 cookies 参数即可。

测试后,发现同样可以正常登录。

5.3 Session 维持

在 requests 中,如果直接利用 get 或 post 等方法的确可以做到模拟网页的请求,但是这实际上是相当于不同的 Session,相当于你用两个浏览器打开了不同的页面。

设想这样一个场景,第一个请求利用 post 方法登录了某个网站,第二次想获取成功登录后的自己的个人信息,你又用了一次 get 方法去请求个人信息页面。实际上,这相当于打开了两个浏览器,是两个完全不相关的 Session,能成功获取个人信息吗?当然不能。

有人会问,我在两次请求时设置一样的 Cookies 不就行了?可以,但这样做起来很烦琐,我们有更简单的解决方法。

解决这个问题的主要方法就是维持同一个 Session,相当于打开一个新的浏览器选项卡而不是新开一个浏览器。但我又不想每次设置 Cookies,那该怎么办呢?这时候就有了新的利器 ——Session 对象。

利用它,我们可以方便地维护一个 Session,而且不用担心 Cookies 的问题,它会帮我们自动处理好。示例如下:

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

这里我们请求了一个测试网址 http://httpbin.org/cookies/set/number/123456789。请求这个网址时,可以设置一个 cookie,名称叫作 number,内容是 123456789,随后又请求了 http://httpbin.org/cookies,此网址可以获取当前的 Cookies。

这样能成功获取到设置的 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 和不同 Session 的区别了吧!

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

5.4 SSL 证书验证

现在很多网站都要求使用 HTTPS 协议,但是有些网站可能并没有设置好 HTTPS 证书,或者网站的 HTTPS 证书不被 CA 机构认可,这时候,这些网站可能就会出现 SSL 证书错误的提示。

比如这个示例网站:https://static2.scrape.cuiqingcai.com/。

如果我们用 Chrome 浏览器打开这个 URL,则会提示「您的连接不是私密连接」这样的错误,如图所示:

img

我们可以在浏览器中通过一些设置来忽略证书的验证。

但是如果我们想用 requests 来请求这类网站,会遇到什么问题呢?我们用代码来试一下:

import requestsresponse = requests.get('https://static2.scrape.cuiqingcai.com/')print(response.status_code)

运行结果如下:

requests.exceptions.SSLError: HTTPSConnectionPool(host='static2.scrape.cuiqingcai.com', port=443): Max retries exceeded with url: / (Caused by SSLError(SSLError("bad handshake: Error([('SSL routines', 'tls_process_server_certificate', 'certificate verify failed')])")))

可以看到,这里直接抛出了 SSLError 错误,原因就是因为我们请求的 URL 的证书是无效的。

那如果我们一定要爬取这个网站怎么办呢?我们可以使用 verify 参数控制是否验证证书,如果将其设置为 False,在请求时就不会再验证证书是否有效。如果不加 verify 参数的话,默认值是 True,会自动验证。

阅读全文: http://gitbook.cn/gitchat/activity/5e69f32d910caf309574e833

您还可以下载 CSDN 旗下精品原创内容社区 GitChat App ,阅读更多 GitChat 专享技术内容哦。

FtooAtPSkEJwnW-9xkCLqSTRpBKX

关注
打赏
1560489824
查看更多评论
立即登录/注册

微信扫码登录

0.0935s