Python爬虫中urllib3与urllib的区别是什么


Posted in Python onJuly 21, 2021

urllib库

urllib 是一个用来处理网络请求的python标准库,它包含4个模块。

  • urllib.request---请求模块,用于发起网络请求
  • urllib.parse---解析模块,用于解析URL
  • urllib.error---异常处理模块,用于处理request引起的异常
  • urllib.robotparser robots.tx---用于解析robots.txt文件

urllib.request模块

request模块主要负责构造和发起网络请求,并在其中添加Headers,Proxy等。 利用它可以模拟浏览器的请求发起过程。

  • 发起网络请求
  • 操作cookie
  • 添加Headers
  • 使用代理

关于urllib.request.urlopen参数的介绍

urllib.request.urlopen(url, data=None, [timeout, ]*, cafile=None, capath=None, cadefault=False, context=None)

urlopen是一个简单发送网络请求的方法。它接收一个字符串格式的url,它会向传入的url发送网络请求,然后返回结果。

先写一个简单的例子:

from urllib import request
response = request.urlopen(url='http://www.httpbin.org/get')
print(response.read().decode())

urlopen默认会发送get请求,当传入data参数时,则会发起POST请求。data参数是字节类型、者类文件对象或可迭代对象。

from urllib import request
response = request.urlopen(url='http://www.httpbin.org/post',
                           data=b'username=q123&password=123')
print(response.read().decode())

还才可以设置超时,如果请求超过设置时间,则抛出异常。timeout没有指定则用系统默认设置,timeout只对,http,https以及ftp连接起作用。它以秒为单位,比如可以设置timeout=0.1 超时时间为0.1秒。

from urllib import request
response = request.urlopen(url='https://www.baidu.com/',timeout=0.1)

Request对象

利用openurl可以发起最基本的请求,但这几个简单的参数不足以构建一个完整的请求,可以利用更强大的Request对象来构建更加完整的请求。

1 . 请求头添加

通过urllib发送的请求会有一个默认的Headers: “User-Agent”:“Python-urllib/3.6”,指明请求是由urllib发送的。所以遇到一些验证User-Agent的网站时,需要我们自定义Headers把自己伪装起来。

from urllib import request
headers ={
    'Referer': 'https://www.baidu.com/s?ie=utf-8&f=3&rsv_bp=1&tn=baidu&wd=python%20urllib%E5%BA%93&oq=python%2520urllib%25E5%25BA%2593&rsv_pq=947af0af001c94d0&rsv_t=66135egC273yN5Uj589q%2FvA844PvH9087sbPe9ZJsjA8JA10Z2b3%2BtWMpwo&rqlang=cn&rsv_enter=0&prefixsug=python%2520urllib%25E5%25BA%2593&rsp=0',
     'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.121 Safari/537.36'
}
response = request.Request(url='https://www.baidu.com/',headers=headers)
response = request.urlopen(response)
print(response.read().decode())

2. 操作cookie

在开发爬虫过程中,对cookie的处理非常重要,urllib的cookie的处理如下案例

from urllib import request
from http import cookiejar
# 创建一个cookie对象
cookie = cookiejar.CookieJar()

# 创一个cookie处理器
cookies = request.HTTPCookieProcessor(cookie)

# 以它为参数,创建opener对象
opener = request.build_opener(cookies)
# 使用这个opener 来发请求
res =opener.open('https://www.baidu.com/')

print(cookies.cookiejar)

3. 设置代理

运行爬虫的时候,经常会出现被封IP的情况,这时我们就需要使用ip代理来处理,urllib的IP代理的设置如下:

from urllib import request
url ='http://httpbin.org/ip'

#代理地址
proxy ={'http':'172.0.0.1:3128'}

# 代理处理器
proxies =request.ProxyBasicAuthHandler(proxy)

# 创建opener对象
opener = request.build_opener(proxies)

res =opener.open(url)
print(res.read().decode())

urlib库中的类或或者方法,在发送网络请求后,都会返回一个urllib.response的对象。它包含了请求回来的数据结果。它包含了一些属性和方法,供我们处理返回的结果

  • read() 获取响应返回的数据,只能用一次
  • readline() 读取一行
  • info() 获取响应头信息
  • geturl() 获取访问的url
  • getcode() 返回状态码

urllib.parse模块

parse.urlencode() 在发送请求的时候,往往会需要传递很多的参数,如果用字符串方法去拼接会比较麻烦,parse.urlencode()方法就是用来拼接url参数的。

from urllib import parse
params = {'wd':'测试', 'code':1, 'height':188}
res = parse.urlencode(params)
print(res)

打印结果为wd=%E6%B5%8B%E8%AF%95&code=1&height=188

也可以通过parse.parse_qs()方法将它转回字典

print(parse.parse_qs('wd=%E6%B5%8B%E8%AF%95&code=1&height=188'))

urllib.error模块

error模块主要负责处理异常,如果请求出现错误,我们可以用error模块进行处理 主要包含URLError和HTTPError

URLError:是error异常模块的基类,由request模块产生的异常都可以用这个类来处理

HTTPError:是URLError的子类,主要包含三个属性

  • Code:请求的状态码
  • reason:错误的原因
  • headers:响应的报头
from urllib import request,error
try:
    response = request.urlopen("http://pythonsite.com/1111.html")
except error.HTTPError as e:
    print(e.reason)
    print(e.code)
    print(e.headers)
except error.URLError as e:
    print(e.reason)

else:
    print("reqeust successfully")

urllib.robotparse模块 

robotparse模块主要负责处理爬虫协议文件,robots.txt.的解析。

Robots协议(也称为爬虫协议、机器人协议等)的全称是“网络爬虫排除标准”(Robots Exclusion Protocol),网站通过Robots协议告诉搜索引擎哪些页面可以抓取,哪些页面不能抓取

网络库urllib3

urllib3是比urllib库更强大的存在,目前已经有许多的原生系统已经开始使用urllib3。

urllib3具有如下优点:

  • 支持HTTP和SOCKS代理
  • 支持压缩编码
  • 100%测试覆盖率
  • 具有链接池
  • 线程安全
  • 客户端SLL/TLS验证
  • 协助处理重复请求和HTTP重定位
  • 使用multipart编码上传文件

因为urllib3并不是Python的标准库,所以我们使用之前,需要进行下载安装,具体命令如下所示:

pip install urllib3
#或
conda install urllib3

下面,我们来讲解urllib3库的使用方式。

网络请求

GET请求

首先,在我们使用urllib3库进行网络请求时,需创建PoolManager类的实例,该类用于管理线程池。

下面,我们来通过urllib访问百度,并返回查询的结果,示例如下:

import urllib3

http = urllib3.PoolManager()
url = 'http://www.baidu.com/s'
headers = {
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36'
}
response = http.request('GET', url, fields={'wd': '机器学习'}, headers=headers)
result = response.data.decode('UTF-8')
print(result)

运行之后,效果如下:

Python爬虫中urllib3与urllib的区别是什么

这里,我们通过fields参数指定GET的请求字段。不过,这里先一步讲解了请求头,其实是百度有安全机制,读者可以去掉headers参数试试。会返回百度的安全验证页面。

POST请求

如果需要向服务器提交表单或者比较复杂的数据,就需要使用到POST请求。POST请求比较简单,仅仅只是将请求的第一个参数改为“POST”即可。

示例如下:

import urllib3

http = urllib3.PoolManager()
url = 'http://httpbin.org/post'
headers = {
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36'
}
response = http.request('POST', url, fields={'username': 'name', 'age': '123456'}, headers=headers)
result = response.data.decode('UTF-8')
print(result)

运行之后,返回如下数据:

Python爬虫中urllib3与urllib的区别是什么

HTTP响应头

使用urllib3库进行网络访问时,其返回的HTTPResponse。默认有一些携带的参数,其中就包括info方法。它能返回响应头数据,示例如下:

import urllib3

http = urllib3.PoolManager()
url = 'http://www.baidu.com/s'
headers = {
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36'
}
response = http.request('POST', url, fields={'wd': '机器学习'}, headers=headers)
for key in response.info().keys():
    print('key:',response.info()[key])

运行之后,返回的响应数据如下:

Python爬虫中urllib3与urllib的区别是什么

上传文件

首先,我们需要简单的实现一个文件上传的服务器代码,这里我们使用Flask搭建一个简单的服务器Python程序,代码如下:

import flask
import os

UPLOAD_FILE = 'uploads'
app = flask.Flask(__name__)
@app.route('/', methods=['POST'])
def upload_file():
    file = flask.request.files['file']
    if file:
        file.save(os.path.join(UPLOAD_FILE, os.path.basename(file.filename)))
        return '文件上传成功'
    else:
        return '文件上传失败'

if __name__ == '__main__':
    app.run()

运行之后,它会一直等待客户端上传文件。

这个时候,我们再来实现urllib3是如何上传文件的,示例如下:

import urllib3

http = urllib3.PoolManager()
with open('1.jpg', 'rb') as f:
    fileData = f.read()
url = 'http://127.0.0.1:5000'
response = http.request('POST', url, fields={'file': ('1.jpg', fileData, 'image/jpeg')})
print(response.data.decode('UTF-8'))

默认flask搭建的服务器,其接口为5000,也就是通过127.0.0.1:5000进行访问。运行之后,就会在uploads文件夹下创建一个1.jpg的图片。

同时,控制台会输出文件上传成功,而服务器会返回状态码200。

这里,上传文件就1一个键值对,其中file代表服务器上传文件的字段。值的元组里,fileData为文件的二进制形式,'image/jpeg'代表上传文件的格式(可以省略)。

超时处理

urllib3库其HTTP的底层都是基于Socket实现的,而Socket超时又分为连接超时与读超时。

其中,连接超时表示在连接的过程中,由于服务器的问题或域名弄错了,而导致的无法连接的情况抛出的异常。

读超时表示从服务器读取数据时由于服务器的问题,导致长时间无法正常读取数据而导致的异常。

通常,我们超时的设置有2种,一种是通过http.request(timeout)进行设置,一种是通过PoolManager()连接池进行设置。示例如下:

from urllib3 import *

http = PoolManager(timeout=Timeout(connect=2.0, read=2.0))
with open('1.jpg', 'rb') as f:
    fileData = f.read()
url = 'http://127.0.0.1:5000'
try:
    response = http.request('POST', url, timeout=Timeout(connect=2.0, read=4.0))
    print(response.data.decode('UTF-8'))
except Exception as e:
    print(e)

需要注意的是,通过连接池PoolManager进行设置的超时,是全局超时时间,哪怕你后边的请求不设置,也是默认使用的这个超时。如果同时设置了request的超时,那么以request为准。

到此这篇关于Python爬虫中urllib3与urllib的区别是什么的文章就介绍到这了,更多相关Python urllib3 urllib内容请搜索三水点靠木以前的文章或继续浏览下面的相关文章希望大家以后多多支持三水点靠木!

Python 相关文章推荐
python dict remove数组删除(del,pop)
Mar 24 Python
pygame学习笔记(2):画点的三种方法和动画实例
Apr 15 Python
Python中实现三目运算的方法
Jun 21 Python
python修改字典内key对应值的方法
Jul 11 Python
浅谈pytorch和Numpy的区别以及相互转换方法
Jul 26 Python
pycharm修改界面主题颜色的方法
Jan 17 Python
利用ImageAI库只需几行python代码实现目标检测
Aug 09 Python
利用python实现PSO算法优化二元函数
Nov 13 Python
python kafka 多线程消费者&手动提交实例
Dec 21 Python
Python操作dict时避免出现KeyError的几种解决方法
Sep 20 Python
Django Model层F,Q对象和聚合函数原理解析
Nov 12 Python
python利用文件时间批量重命名照片和视频
Feb 09 Python
python Django框架快速入门教程(后台管理)
Python编写nmap扫描工具
Jul 21 #Python
Django模型层实现多表关系创建和多表操作
Jul 21 #Python
Python基本数据类型之字符串str
Jul 21 #Python
Python中22个万用公式的小结
Jul 21 #Python
python字典的元素访问实例详解
Jul 21 #Python
Opencv实现二维直方图的计算及绘制
You might like
一个目录遍历函数
2006/10/09 PHP
php接口和抽象类使用示例详解
2014/03/02 PHP
php递归调用删除数组空值元素的方法
2015/04/28 PHP
thinkphp3.2.3 分页代码分享
2016/07/28 PHP
PHP常用函数总结(180多个)
2016/12/25 PHP
PHP5.6.8连接SQL Server 2008 R2数据库常用技巧分析总结
2019/05/06 PHP
jquery validate.js表单验证的基本用法入门
2010/05/13 Javascript
ASP.NET jQuery 实例16 通过控件CustomValidator验证RadioButtonList
2012/02/03 Javascript
Javascript查询DBpedia小应用实例学习
2013/03/07 Javascript
跟我学Nodejs(一)--- Node.js简介及安装开发环境
2014/05/20 NodeJs
js中的内部属性与delete操作符介绍
2015/08/10 Javascript
vue.js表格分页示例
2016/10/18 Javascript
EasyUI学习之Combobox下拉列表(1)
2016/12/29 Javascript
Angular.js中ng-if、ng-show和ng-hide的区别介绍
2017/01/20 Javascript
Bootstrap table右键功能实现方法
2017/02/20 Javascript
JS实现的二叉树算法完整实例
2017/04/06 Javascript
微信小程序开发之数据存储 参数传递 数据缓存
2017/04/13 Javascript
React-Native之定时器Timer的实现代码
2017/10/04 Javascript
Bootbox将后台JSON数据填充Form表单的实例代码
2018/09/10 Javascript
nodejs中各种加密算法的实现详解
2019/07/11 NodeJs
[01:04:30]Fnatic vs Mineski 2018国际邀请赛小组赛BO2 第二场 8.17
2018/08/18 DOTA
python中随机函数random用法实例
2015/04/30 Python
详解Python中expandtabs()方法的使用
2015/05/18 Python
纯python实现机器学习之kNN算法示例
2018/03/01 Python
python代码如何实现余弦相似性计算
2020/02/09 Python
解决Python import docx出错DLL load failed的问题
2020/02/13 Python
HTML5 canvas画矩形时出现边框样式不一致的解决方法
2013/10/14 HTML / CSS
到底Java是如何传递参数的?是by value或by reference?
2012/07/13 面试题
什么是GWT的Module
2013/01/20 面试题
幼儿园标语大全
2014/06/19 职场文书
2014年反洗钱工作总结
2014/11/22 职场文书
表扬稿格式范文
2015/01/16 职场文书
关于倡议书的范文
2015/04/29 职场文书
运动会100米加油稿
2015/07/21 职场文书
《观潮》教学反思
2016/02/17 职场文书
ubuntu如何搭建vsftpd服务器
2022/12/24 Servers