爬虫网络库(4.urllib3网络库)

目录内容

        • urllib侧重于URL的请求构造
        • urllib2侧重于HTTP请求的处理
        • urllib3服务于升级的HTTP1.1标准,且拥有高效HTTP连接池管理以及HTTP代理服务的功能库
  • 4.1 sendrequest发送请求
  • 4.2 sendpost发送HTTP POST请求
  • 4.3 request_header请求头
  • 4.4 headers_response响应头信息
  • 4.5 upload上传文件到服务器
  • 4.6 Timeout 超时

urllib侧重于URL的请求构造

urllib2侧重于HTTP请求的处理

urllib3服务于升级的HTTP1.1标准,且拥有高效HTTP连接池管理以及HTTP代理服务的功能库

urllib3内容:
1、线程安全
2、连接池
3、客户端SSL/TLS验证
4、使用Multipart编码上传文件
5、协助处理重复请求和HTTP重定位
6、支持压缩编码
7、支持HTTP和SOCKS代理
8、100%测试覆盖率

4.1 sendrequest发送请求

  1. 引用urllib3模块,创建PoolManager类实例,管理连接池,可以通过request方法发送GET请求,
  2. request方法的返回值就是服务端的响应结果,可以通过data属性直接可以获得服务端的响应数据
from urllib3 import *
# urlencode函数在urllib.parse模块中
from urllib.parse import urlencode
# 调用disable_warnings函数可以阻止显示警告信息
disable_warnings()
# 创建PoolManager类的实例
http = PoolManager()

'''# 下面的代码通过组合URL的方式向百度发送请求
url = 'http://www.baidu.com/s?' + urlencode({'wd':'极客起源'})
print(url)
response = http.request('GET', url)
'''
url = 'http://www.baidu.com/s'
# 直接使用fields关键字参数指定GET请求字段
response = http.request('GET',url,fields={'wd':'极客起源'})
# 获取百度服务端的返回值(byte形式),并使用UTF-8对其进行编码
data = response.data.decode('UTF-8')
# 输出百度服务端返回的内容
print(data)

4.2 sendpost发送HTTP POST请求

  1. 通过flask模块不安写一个可以处理HTTP POST请求的服务端程序,
# 支持HTTP POSt请求的服务端程序
from flask import Flask,request
# 创建Flask对象,任何基于flask模块的服务端应用都必须创建Flask对象
app = Flask(__name__)
# 设置/register路由,该路由可以处理HTTP POSt请求
@app.route('/register',methods=['POST'])
def register():
    # 输出名为name的请求字段值
    print(request.form.get('name'))
    # 输出名为age的请求字段值
    print(request.form.get('age'))
    # 向客户端发送“注册成功”的信息
    return '注册成功'
if __name__ == '__main__':
    # 开始运行服务端程序,默认端口好为5000
    app.run()
  1. 使用urllib3模块中相应的API向这个服务端程序发送HTTP POST请求,然后输出服务端的返回结果
from urllib3 import *
disable_warnings()
http = PoolManager()
# 指定要提交的HTTP POST请求的URL,/register是路由
url = 'http://localhost:5000/register'
# 想服务端发送HTTP PST请求,用fields关键字参数指定请求字段名和值
response = http.request('POST',url,fields={'name':'李青','age':18})
# 获取服务端返回数据
data = response.data.decode('utf-8')
# 输出服务端返回的数据
print(data)
  1. 运行结果
    爬虫网络库(4.urllib3网络库)_第1张图片

爬虫网络库(4.urllib3网络库)_第2张图片

4.3 request_header请求头

通过request方法访问天猫商城的搜索功能,搜索功能的服务端必须依赖于HTTP请求头的cookie字段

  1. 第一步登录天猫获取cookie,按F12进入开发者模式爬虫网络库(4.urllib3网络库)_第3张图片
    爬虫网络库(4.urllib3网络库)_第4张图片
  2. 将cookie的内容保存到文本文档中,方便读取
    爬虫网络库(4.urllib3网络库)_第5张图片
  3. 通过读取cookie.txt的内容并加入到请求头中,编写代码如下
from urllib3 import *
import re
disable_warnings()
http = PoolManager()
# 定义天猫的搜索页面URL
url = 'https://list.tmall.com/search_product.htm?q=1&type=p&vmarket=&spm=875.7931836%2FB.a2227oh.d100&from=mallfp..pc_1_searchbutton'
# 从headers.txt文件读取HTTP请求头,并将其转换为字典形式
def str2Headers(file):
    headerDict = {}
    f = open(file,'r')
    # 读取headers.txt文件中的所有内容
    headersText = f.read()
    headers = re.split('\n',headersText)
    for header in headers:
        result = re.split(':',header,maxsplit = 1)
        headerDict[result[0]] = result[1]
    f.close()
    return headerDict
headers = str2Headers('headers.txt')
# 请求天猫的搜索页面,并传递HTTP请求头
response = http.request('GET',url,headers=headers)
# 将服务端返回的数据按GB18030格式解码
data = response.data.decode('GB18030')
print(data)

由上述代码可见,请求头是一种字典形式存放数据,cookie十分重要,不要随便泄漏。

4.4 headers_response响应头信息

使用HTTPResponse.info方法可以非常容易获取HTTP响应头的信息。其中HTTPResponse对象是request方法的返回值

# 获取百度的响应头消息
from urllib3 import *
disable_warnings()
http = PoolManager()
url = 'http://www.baidu.com'
response = http.request('GET',url)
# 输出所有响应头字段和值
for key in response.info().keys():
    print(key,':',response.info()[key])

4.5 upload上传文件到服务器

# http是PoolManager类的实例
# 上传任意类型的文件(未指定文件类型)
# http.request('POST',url,fields={'files':(filename,fileData)})
# 上传文本类型的文件
# http.request('POST',url,fields={'files':(filename,fileData,'text/plain')})
# 上传jpeg类型的文件
# http.request('POST',url,fields={'files':(filename,fileData,'image/jpeg')})
  1. 编写服务器端
ps = '''实现了将文件上传到服务端的程序,可以通过输入本地文件名来上传任何类型的文件'''
import os
from flask import Flask,request
# 定义服务端保存上传文件的位置
UPLOAD_FOLDER = 'uploads'
app = Flask(__name__)
# 用于接收上传文件的路由需要使用POST方法
@app.route('/',methods=['POST'])
def upload_file():
    # 获取上传文件的内容
    file = request.files['files']
    if file:
        # 将上传的文件保存到upload子目录中
        file.save(os.path.join(UPLOAD_FOLDER, os.path.basename(file.filename)))
        return "文件上传成功"

if __name__ == '__main__':
    app.run()
  1. 编写上传文件代码
from urllib3 import *
disable_warnings()
http = PoolManager()
# 定义上传文件的服务端URL
url = 'http://localhost:5000'
while True:
    # 输入上传文件的名字
    filename = input('请输入要上传的文件名字(必须在当前目录下):')
    # 如果什么也没有输入,退出循环
    if not filename:
        break
    # 用二进制的方式打开要上传的文件名,然后读取文件的所有内容,使用with语句会自动关闭打开的文件
    with open(filename,'rb') as fp:
        fileData = fp.read()
    # 上传文件
    response = http.request('POST',url,fields={'files':(filename,fileData)})
    # 输出服务端的返回结果,本例是“文件上传成功”
    print(response.data.decode('utf-8'))
  1. 注意:此处输入同一目录下的文件名直接上传,文件结构如下:爬虫网络库(4.urllib3网络库)_第6张图片

4.6 Timeout 超时

from urllib3 import *
disable_warnings()
# 通过PoolManager类的构造方法指定默认的连接超时和读超时
http = PoolManager(timeout=Timeout(connect=2.0,read=2.0))
url1 = 'https://www.baidu1122.com'
url2 = 'http://httpbin.org/delay/3'
try:
    # 此处代码需要放在try…except中,否则一旦抛出异常,后面的代码将无法执行
    # 下面的代码会抛出异常,因为域名www.baidu1122.com并不存在
    # 由于连接超时设为2秒,
    http.request('GET', url1,timeout=Timeout(connect=2.0,read=4.0))
except Exception as e:
    print(e)
print('------------')
# 由于读超时为4秒,而url2指定的Url在3秒后就返回数据,所以不会抛出异常,
# 会正常输出服务器的返回结果
response = http.request('GET', url2,timeout=Timeout(connect=2.0,read=4.0))
print(response.info())
print('------------')
print(response.info()['Content-Length'])
# 由于读超时为2秒,所以会在2秒后抛出读超时异常
http.request('GET', url2,timeout=Timeout(connect=2.0,read=2.0))

你可能感兴趣的:(高级爬虫案例教程,爬虫,python)