文章目录
- 1 requests库的使用
- 1.1 准备工作
- 1.2 实例引入
- 1. 3 GET请求
- 1.3.1 基本实例
- 1.3.2 抓取网页
- 1.3.3 抓取二进制数据
- 1.3.4 添加请求头
- 1.4 POST请求
- 1.5 响应
- 1.6 高级用法
- 1.6.1 文件上传
- 1.6.2 Cookie设置
- 1.6.3 Session维持
- 1.6.4 SSL证书验证
- 1.6.5 超时设置
- 1.6.6 身份认证
- 1.6.7 代理设置
- 1.6.8 Prepared Request
1 requests库的使用
使用urllib库处理页面验证和Cookie时,需要写
Opener
类和Handler
类来处理,
此外实现POST、PUT等请求时的写法也不太方便
requests库比urllib库更为强大,Cookie、登录验证、代理设置都很简单。
1.1 准备工作
requests是第三方库,是需要安装的,
可以使用pip3来进行安装
pip3 install requests
更多安装信息可以参考https://setup.scrape.center/requests
1.2 实例引入
urllib库中的urlopen方法实际上是以GET方式请求网页,
requests库中相应的方法就是get方法
代码如下:
def get_base():
import requests
r = requests.get('https://www.baidu.com')
print(type(r)) # 响应的类型
print(r.status_code) # 响应状态码
print(type(r.text)) # 响应体的类型
print(r.text[:100]) # 响应体内容
print(r.cookies) # cookie
运行结果如下图所示:
可以发现,返回的响应的类型是requests.models.Response
响应体的类型是字符串
Cookie的类型是RequestsCookieJar
与get方法相似,同样可以采用一句话完成post、put、delete、patch等请求。
1. 3 GET请求
HTTPS请求中最常见的就是GET请求,先详细了解一个利用requests库构建GET请求。
1.3.1 基本实例
首先我们想向测试网站发送一个GET请求,
测试网站会测试发起的是否是GET请求,如果是将返回响应的请求信息。
代码如下:
def get_test():
import requests
r = requests.get('https://www.httpbin.org/get')
print(r.text)
运行结果如下图所示:
发送GET请求时,我们可以利用get方法中的params
参数来直接传递参数,而不必再进行格式转换。
代码如下:
def get_test():
import requests
data = {
'name': '我是测试数据',
'aget': 13
}
r = requests.get('https://www.httpbin.org/get', params=data)
print(r.text)
运行结果如下:
响应体的类型虽然是str类型,但是是JSON
格式的,如果想直接解析返回结果,得到一个JSON格式的数据,可以直接调用json方法
代码如下:
def get_test():
import requests
data = {
'name': '我是测试数据',
'aget': 13
}
r = requests.get('https://www.httpbin.org/get', params=data)
print(type(r.text))
print(r.json())
print(type(r.json()))
运行的结果如下:
从运行结果可以看出,json 方法可以把返回结果转为字典。
但如果返回结果不是JSON格式,就会出现解析错误,抛出json.decoder.JSONDecodeError
异常
1.3.2 抓取网页
我们以一个实例页面作为演示,向里面加入一点提取信息的逻辑
使用正则表达式匹配所有的电影标题。
代码如下:
def get_h2():
import requests
import re
r = requests.get('https://ssr1.scrape.center/')
patters = re.compile('<h2.*?>(.*?)</h2>', re.S)
titles = re.findall(patters, r.text)
print(titles)
运行结果如下图所示:
1.3.3 抓取二进制数据
上面是抓取了网站的一个页面,实际上返回的是一个HTML文档,如果想要抓取图片、音频、视频等文件,怎么办?
图片、音频、视频本质上都是二进制码组成,有特定的保存格式和对应得解析方式。
因此我们想要抓取它们,必须拿到它们的二进制数据。
以网站的站点图标为例
代码如下:
def get_ico():
import requests
r = requests.get('https://scrape.center/favicon.ico')
print(r.content)
运行的结果如下图所示:
其输出的结果,最前面有一个b,说明这是bytes类型的数据。
实际上,我们不用管其输出的是什么,只需要将提取到的信息保存下来就行了
代码如下:
def get_ico():
import requests
r = requests.get('https://scrape.center/favicon.ico')
with open('favicon.ico', 'wb') as f: # 以二进制写的形式打开文件favicon.ico。如果不存在文件,就会新建。
f.write(r.content) # 将二进制数据写入到打开的文件中
运行之后,我目录中出现一个favicon.ico的图标,如下图所示。
这就是把二进制图片保存成了一张图片。
可以利用同样的方法来保存音频和视频
1.3.4 添加请求头
在进行爬虫时,我们通常会设置请求头
get方法中有一个参数是headers
,便是用来添加请求头信息的。
传入的参数是字典。
代码如下:
def get_set_headers():
import requests
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) '
'AppleWebKit/537.36 (KHTML, like Gecko) Chrome/109.0.0.0 Safari/537.36'
}
r = requests.get('https://ssr1.scrape.center/', headers=headers)
print(r.text)
1.4 POST请求
HTTP中另一种常见的请求方式是POST
使用requests来进行POST请求同样很简单
以测试网站为例。
该网站判断请求是否是POST方式,如果是,返回相关的请求信息。
代码如下:
def post_test():
import requests
data = {
'name': 'wo shi post',
'get': 33
}
r = requests.post('https://www.httpbin.org/post', data=data)
print(r.text)
运行结果如下图所示:
可以看出 我们传入的data参数在form部分显示,这就表明data参数是提交的数据,这就证明POST方法请求成功了。
1.5 响应
请求发送之后,会得到响应,在之前的实例中,我们通过text、content获取了响应的内容。
除了这两个之外还有很多的属性和方法可以获得其他信息
如状态码(status_code)、响应头(headers)、Cookie(cookies)、URL(url)、请求历史(history)等等
状态码是来表示响应状态的,除了通过判断状态码是不是200,可以知道爬虫是否成功
requests库提供了一个内置的状态码查询对象requests.codes
实例如下:
def codes_test():
import requests
r = requests.get('https://ssr1.scrape.center/')
exit() if not r.status_code == requests.codes.ok else print('Request Successful')
这里通过比较返回码(
statue_code
)和内置的表示成功的状态码(ok)来保证请求是否得到了正常响应。
如果是,就输出请求成功的消息,否则程序终止运行。
更多的返回码和相应的内置状态码见链接
1.6 高级用法
1.6.1 文件上传
requests库还可以实现文件上传功能
我们利用之前保存的文件favicon.ico来模拟文件上传过程
代码如下:
def file_up():
import requests
files = {'file': open('favicon.ico', 'rb')}
r = requests.post('https://www.httpbin.org/post', files=files)
print(r.text)
执行的结果如下图所示:
因为file参数值太长,因此截取了一下。
1.6.2 Cookie设置
Cookie的获取
代码如下:
def get_cookie():
import requests
r = requests.get('https://baidu.com')
print(r.cookies)
for key, item in r.cookies.items():
print(key + '=' + item)
运行结果如图所示:
可以使用Cookie来维持登录状态,
先登录百度,将请求头中的Cookie复制下来,
然后设置headers里的Cookie,最后发送请求。
还可以通过
RequestsCookieJar
来设置cookie
代码如下:
其中cookie的值是从百度请求头中的cookies
复制下来的,这里进行了缩减。实际运行代码时要原封不动传入进去。
def set_cookie():
from requests import cookies
import requests
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/109.0.0.0 Safari/537.36'
}
cookies = 'BIDUPSID=B58F86B023F80C9FC948C08AFE0EBE75; PSTM=1668075804; BDUSS=V........'
jar = requests.cookies.RequestsCookieJar() # 新建一个RequestCookieJar对象
for cookie in cookies.split(';'): # 利用split方法对复制下来的Cookie内容做分隔
key, value = cookie.split('=', 1)
jar.set(key, value) # 利用set方法设置好每个Cookie条目的键名和键值,
r = requests.get('https://baidu.com', cookies=jar, headers=headers) # 设置cookie、headers 发送get请求
print(r.content)
其输出结果如下图所示:
显然我们成功获取到了网页信息,
此处是存在编码问题的,但是目前我尚未解决!!!!!!
1.6.3 Session维持
利用
Session
可以做到模拟同一个会话而不用担心Cookie的问题,
通常在模拟登录成功之后,进行下一步操作时用到
请求一个测试网址 https://www.httpbin.org/cookies/set/number/123456789
在请求网址时,设置了一个Cookie条目,名称是number,内容是123456789
随后用请求了https://www.httpbin.org/cookies,来获取网站的cookie
代码如下:
def session_test():
import requests
s = requests.Session()
s.get('https://www.httpbin.org/cookies/set/number/123456789')
r = s.get('https://www.httpbin.org/cookies')
print(r.text)
运行的结果如下:
1.6.4 SSL证书验证
现在很多网站使用HTTPS协议,但是有些网站可能并没有设置好
HTTPS
证书,或者网站的HTTPS证书可能不被CA机构认可,这时这些网站就可能出现SSL证书错误的提示
例如实例网站,使用Chrome浏览器啊打开事,会提示"您的连接不是私密连接"这样的错误。
如下图所示:
在浏览器中我们可以通过一些设置来忽略证书的验证
如果用requests
库请求这类网站,会抛出SSLError
错误
代码如下:
def SSL_test():
import requests
r = requests.get('https://ssr2.scrape.center')
print(r.status_code)
输入的错误信息如下:
代码抛出SSLError
错误,是因为我们请求的URL的证书是无效的
我们通过设置verify
参数,来控制是够验证证书,
将其设置为False
,那么请求时就不会再验证证书是否有效
改写上述代码:
def SSL_test():
import requests
r = requests.get('https://ssr2.scrape.center', verify=False)
print(r.status_code)
运行结果如下图所示:
可以看出,已经打印出请求成功的状态码了,但是也报了一个警告
它建议我们给它指定证书,同样的,我们可以通过设置忽略警告的方式来屏蔽这个警告
修改上述代码如下:
def SSL_test():
import requests
import urllib3
urllib3.disable_warnings()
r = requests.get('https://ssr2.scrape.center', verify=False)
print(r.status_code)
或者通过捕获警告到日志的方式忽略警告
代码如下:
def SSL_test():
import requests
# import urllib3
# urllib3.disable_warnings()
import logging
logging.captureWarnings(True)
r = requests.get('https://ssr2.scrape.center', verify=False)
print(r.status_code)
当然还可以通过
cert
参数指定一个本地证书用作客户端证书,这可以是单个文件(包含密钥和证书)或者一个包含两个文件路径的元组
此外,本地私有证书的key
必须是解密状态。
1.6.5 超时设置
在本机网络状态不好或者服务器网络响应太慢甚至无响应时, 我们可能会等待很久才能接到响应,甚至因为接收不到响应而报错。
为了防止服务器不能及时响应,通常设置一个超时时间,如果超过这个时间还没有得到响应,就报错
这就需要用到timeout
参数,其值是从发出请求到服务器返回响应的时间
代码如下
def timeout_test():
import requests
r = requests.get('https://www.httpbin.org/get', timeout=1)
print(r.text)
实际上,请求分为两个阶段:连接(connection)和读取(read)
如果想要分别指定用作连接和读取的timeout,可以传入一个元组
代码如下:
def timeout_test():
import requests
r = requests.get('https://www.httpbin.org/get', timeout=(0.4, 0.7))
print(r.text)
如果想要永久等待,可以将
timeout
设置为None
或者不设置。
1.6.6 身份认证
在访问启用了基本身份认证的网站时,会首先弹出一个认证窗口,让我们输入用户名和密码
在requests库中,我们可以通过auth
参数进行设置
以网站为例
代码如下:
def auth_test():
import requests
r = requests.get('https://ssr3.scrape.center', auth=('admin', 'admin'))
print(r.status_code)
我们在auth参数中传入的是
HTTPBasicAuth
类,
实际上,我们可以直接传入一个元组,会默认使用HTTPBasicAuth
这个类来认证
requests库还提供其他的认证方式,如
OAuth
认证,但是此时需要安装oauth包
1.6.7 代理设置
为了防止在爬虫过程中,由于请求次数过多而被封IP,我们可以通过
proxies
设置代理防止IP被封
除了基本的HTTP代理之外,requests库还支持SOCKS
协议的代理,但是需要安装socks库
1.6.8 Prepared Request
我们可以通过requests库中的get和post方法发送请求。
在requests
内部,在发送请求时,构造了一个Request
对象,并给其赋予个各种参数
然后把这个Request
对象发送出去,请求成功后会得到一个Response
对象,最后解析这个对象
Request
对象,实际上就是Prepared Request
我们之后构造一个Prepared Request
对象来发送一个post请求
代码如下:
def my_post():
from requests import Request, Session
url = 'https://www.httpbin.org/post'
data = {'name': 'germey'}
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/109.0.0.0 Safari/537.36'
}
s = Session()
req = Request('POST', url, data=data, headers=headers)
prepped = s.prepare_request(req)
r = s.send(prepped)
print(r.text)
程序运行的结果如下图所示: