文章目录
- 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)
 
程序运行的结果如下图所示:
































