python爬虫入门三:requests库

时间:2021-07-29 08:11:04

urllib库在很多时候都比较繁琐,比如处理Cookies。因此,我们选择学习另一个更为简单易用的HTTP库:Requests。

requests官方文档

1. 什么是Requests

Requests是用python编写,基于urllib,采用Apache2 Licensed开源协议的HTTP库。它比urllib更加简单易用。

2. 使用Requests库

2.1 构建请求

使用requests可以很方便的构建请求:

r = requests.get('https://api.github.com/events')# 构建GET请求r = requests.post('http://httpbin.org/post')     # 构建POST请求r = requests.put('http://httpbin.org/put')    #构建PUT请求

2.1.1 GET请求

import requests

response = requests.get('http://httpbin.org/get')
print(response.text)

2.1.2 带参数的GET请求

使用GET进行请求数据时,其参数全部位于url中。

要使用requests构建一个带参数的GET请求,可以选择将参数和url拼接形成新的url进行请求,或者是将需要传递的参数传入requests.get()方法的params

# 方法一:将拼接后的url传入requests.get()
response = requests.get('http://httpbin.org/get?name=gemey&age=22')

# 方法二:将参数传入requests.get()的params
data = {
    'name': 'gemey',
    'age': 22
}
response = requests.get('http://httpbin.org/get', params=data) 

2.1.3 POST请求

POST请求和GET请求最显著的区别在于,其请求的参数需要与url分离开来。

在requests中,构建POST请求的方法和构建带参数的GET请求方法类似,只需要将需要传递的参数参数requests.post()方法的data

import requests

data ='}

response = requests.post('http://httpbin.org/post', data=data)
print(response.text)

2.1.4 解析json

在python中,要解析json数据,经常使用json.loads()方法。同时,requests也提供了requests.json()方法用于解析数据。

这二者效果一致

import requests
import json

response = requests.get('http://httpbin.org/get')

print(type(response.text))
print(response.json())
# 二者效果一致
print(json.loads(response.text))

2.1.5 获取二进制数据

# 以github一个图标为例
import requests

response = requests.get('https://github.com/favicon.ico')
# requests.content 即为获取的二进制数据
print(type(response.content))
print(response.content)

2.1.6 添加headers信息

为get()的headers参数传入相应的headers信息即可

import requests

# 需要传入的headers信息
header = {
    'User-Agent': 'Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_8; en-us) AppleWebKit/534.50 (KHTML, like Gecko) Version/5.1 Safari/534.50'
}

response = requests.get('http://zhihu.com/explore', headers=header)
print(response.text)

2.2 Response

2.2.1 response属性

print(response.status_code) # 返回状态码
print(response.headers)     # 返回headers信息
print(response.cookies)     # 返回cookies信息
print(response.url)         # 返回访问的url
print(response.history)     # 访问历史记录

2.2.2 response状态码判别

内置状态码判别:requests.codes包含了一系列访问正常的状态码,可用于判别是否连接成功:

import requests

response = requests.get('http://www.jianshu.com')

# 使用内置状态码判定
exit() if not response.status_code==requests.codes.ok else print('Request Successfully')
# 直接判定
exit() if not response.status_code==200 else print('Request Successfully')

2.3 高级操作

2.3.1 文件上传

文件上传,使用POST请求。

import requests

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

2.3.2 获取cookie

response.cookies获取到的是键值对,可以把其中每一条记录都提取出来。

import requests

response = requests.get('https://baidu.com')
print(respnse.cookies)
for key, value in response.cookies.items():
    print(key, value)

2.3.3 会话维持

cookies的作用就是给网站用于维持会话,常用于模拟登陆

使用requests中的session()对象,使得前后两次访问都使用统一浏览器,即维持会话,cookies保持一致。

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

2.3.4 证书验证

在打开使用https协议的页面时,浏览器首先需要对该网页的证书进行验证。如果验证不通过,程序就会报错。比如曾经的12306网站。

因此,就需要设置verify=False关闭证书验证。

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

同时,我们也可以选择使用本地的证书用于验证网页。只需要在cert里传入本地证书即可。

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

2.3.5 代理设置

requests使用代理设置,只需要在请求时传入proxies参数

proxies = {
    'http': 'http://123.0.0.1:23',
    'https': 'https://123.0.0.1:123'
}

response = requests.get('https://www.taobao.com', proxies=proxies)
print(response.status_code)

2.3.6 超时设置

为访问网页设置超时,如果访问网页超过规定的时间,就抛出异常。目的是防止在请求某个网页时时间过长导致程序没有继续运行。

在请求时设置timeout参数即可设置请求网页时耗费的最大时长。如果超过这个时间还没有请求完,程序即报错。

使用requests的exceptions模块进行处理异常报错。

import requests
from requests.exceptions import ReadTimeout

try:
    response = requests.get('http://httpbin.org/get', timeout=0.5)
    print(response.status_code)
except ReadTimeout:
    print('Timeout')

2.3.7 认证设置

在访问某些网站时,需要进行登陆验证。可以在请求时设置auth,传入认证的账户密码

import requests
from requests.exceptions import ReadTimeout

try:
    response = requests.get('http://httpbin.org/get', timeout=0.5)
    print(response.status_code)
except ReadTimeout:
    print('Timeout')

2.3.8 异常处理

使用requests的exceptions模块

import requests
from requests.exceptions import ReadTimeout, HTTPError, RequestException

try:
    response = requests.get('http://httpbin.org/get', timeout=0.5)
    print(response.status_code)
except ReadTimeout:
    print('timeout')
except HTTPError:
    print('http error')
except RequestException:
    print('error')

2.4 保存抓取到的图片

如果我们从网页中爬取图片,那么拿到每一张图片对应的url后,我们需要把图片保存到本地。

urllib库中有一个urlretrieve()方法可以将图片保存到本地,但是requests库中并没有这个功能,我们需要使用文件写入的方法将图片保存到本地

# 以百度首页的logo为例# import requests

# 找到logo对应的url
url = 'https://www.baidu.com/img/bd_logo1.png'
r = requests.get(url)

# 写入本地磁盘# 'wb'是指以二进制格式打开一个文件只用于写入。如果该文件已存在则将其覆盖。如果该文件不存在,创建新文件。
with open('/path/baidu.png', 'wb') as f:  f.write(r.content)

  with...as...的方法可以在写入文件完成后自动关闭文件,不需要我们手动将文件关闭,因而可以避免因忘记关闭文件而浪费资源和干扰已经写入的文件。

  关于使用open()写入文件的具体方式可以参考:python打开与关闭文档

或者,使用urllib的urlretrieve()方法

import urllib

url = 'https://www.baidu.com/img/bd_logo1.png'
urllib.request.urlretrieve(url, '/path/baidu.png')