urllib库(一)request模块:urlopen(),Request() 实现 get/post,urlretrieve() 下载网页文件,ProxyHandler()设置代理

编程入门 行业动态 更新时间:2024-10-12 05:44:34

urllib库(一)request<a href=https://www.elefans.com/category/jswz/34/1771428.html style=模块:urlopen(),Request() 实现 get/post,urlretrieve() 下载网页文件,ProxyHandler()设置代理"/>

urllib库(一)request模块:urlopen(),Request() 实现 get/post,urlretrieve() 下载网页文件,ProxyHandler()设置代理

一、urllib库

python3内置的urllib库不需要安装直接import导入

                             该库中主要模块有
模块含义功能
urllib.request请求模块打开和读取URL
urllib.parse解析模块解析和处理URL
urllib.response响应模块
urllib.error异常处理模块包含了urllib.request产生的异常
urllib.robotparse解析页面的robots.txt
>>> help(urllib)
Help on package urllib:NAMEurllibPACKAGE CONTENTSerrorparserequestresponserobotparserFILEd:\360downloads\python\lib\urllib\__init__.py

二、urllib.requset

(1)urlopen(),Request() 实现 get,post

>>> import urllib
>>> help(urllib.urlopen)
Traceback (most recent call last):File "<stdin>", line 1, in <module>
AttributeError: module 'urllib' has no attribute 'urlopen'
>>> help(urllib.request.urlopen)
Help on function urlopen in module urllib.request:所有和网络请求有关的方法都集到了urllib库下面的request模块
注意直接import urllib不能访问到urllib.urlopen应该是import urllib.request 或from urllib import request
同时要注意这两种导入在调用时的区别 前者要写模块名,后者不写直接调用

1、两种方法使用内置urllib库实现get简单实例


方法一:urllib.request.urlopen()函数实现geturlopen函数定义
urlopen(url, data=None, [timeout, ]*, cafile=None, capath=None, cadefault=False, context=None)url:需要打开的网址 str类型或者urllib.request.Request对象类型data:Post提交的数据,没有这个参数时实现的是get方法/get请求不需要传入data参数Post的数据必须是bytes或者iterable of bytes,不能是str,如果是str需要进行bytes(str,encoding)如果是字典需要用urllib.parse模块里urlencode()编码具体编码方法见后文post实现timeout:设置网站的访问超时时间urllib.request.urlopen()返回'http.client.HTTPResponse'对象
可通过该对象的方法获取某些数据信息和响应信息如(1)f.read(size)/f.readline()/f.readlines() 读取的数据是字节型bytes可调用bytes.decode()方法进行解码转成str类型 如data.decode('utf-8')bytes对象常用方法见后文(2)f.geturl()/f.url 获取请求的url  #(3)f.getcode() 获取本次请求的HTTP响应状态码  #200(4)f.getheaders():表示远程服务器返回的头部全部信息,以列表形式返回,每一个列表元素又是一个有两个元素的元组,分别构成key-value(5)f.getheader(name):获取响应报头中name字段的值 (6)f.info():以字典形式返回HTTPMessage对象,表示远程服务器返回的头信息(7)f.fileno()/f.close() :对HTTPResponse类型数据进行操作具体可通过dir(object),help(object)查看其方法、属性和函数定义import urllib.request
# 构建GET请求
f = urllib.request.urlopen("")
data=f.read()
print(data.decode('utf-8'))>>> type(f)
<class 'http.client.HTTPResponse'>
>>>type(data)
<class 'bytes'>
方法二:urllib.request.Request()实现geturllib.request.Request类定义
class Request(builtins.object)|  Request(url, data=None, headers={}, origin_req_host=None, unverifiable=False, method=None)对比urllib.request.urlopen()方法可以看到urllib.request.Request方法中含有参数列表(0)url str类型(1)data同样必须是bytes(字节流)类型如果是字典,可以用urllib.parse模块里urlencode()编码具体编码方法见后文post实现urllib.request.Request()实现get时和urlopen()一样不需要传入data参数(2)headers因此实现最基本的请求的发起可以用urlopen()但如果要加入headers等信息,就要用Request类来构造请求可以通过请求头伪装浏览器,默认User-Agent是Python-urllib 此时请求发爬虫机制下可能不会返回我们数据(返回空数据)或者返回虚假数据如要伪装chrome浏览器,可以设置User-Agent为Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, 	like Gecko) Chrome/86.0.4240.198 Safari/537.36需要注意参数中headers={}默认值是空字典,headers的类型必须是字典而加入headers的方法有两种(1)构造请求时通过headers参数直接构造传入(2)调用请求实例的add_header()方法添加(3)origin_req_host 指定请求方的host名称或者ip地址(4)unverifiable	设置网页是否需要验证,默认是False,这个参数一般也不用设置(5)method	str类型,指定请求使用的方法,比如GET,POST和PUT等(大写)返回值返回<class 'urllib.request.Request'>对象,作为urlopen(url)的url参数传入||  Methods defined here:||  __init__(self, url, data=None, headers={}, origin_req_host=None, unverifiable=False, method=None)||  add_header(self, key, val)多个键值对之间用逗号隔开add_header(key:value[,key:value])||  add_unredirected_header(self, key, val)||  get_full_url(self)||  get_header(self, header_name, default=None)||  get_method(self)|      Return a string indicating the HTTP request method.||  has_header(self, header_name)||  has_proxy(self)||  header_items(self)||  remove_header(self, header_name)||  set_proxy(self, host, type)|各种方法的使用help,dir自查import urllib.request
request = urllib.request.Request('')
response = urllib.request.urlopen(request)
print(response.read().decode('utf-8'))>>> type(request)
<class 'urllib.request.Request'>
bytes对象常用方法 更多参考help(bytes)/dir(bytes)
class bytes(object)|  bytes(iterable_of_ints) -> bytes|  bytes(string, encoding[, errors]) -> bytes将str对象按照指定编码方式encoding转成bytes对象这在下文实现post会用到|  bytes(bytes_or_buffer) -> immutable copy of bytes_or_buffer|  bytes(int) -> bytes object of size given by the parameter initialized with null bytes

2、两种方法使用内置urllib库实现post的简单实例

方法一:urllib.request.urlopen()实现posturlopen(url, data=None, [timeout, ]*, cafile=None, capath=None, cadefault=False, context=None)实现Post,urlopen()的data参数必须是bytes或者iterable of bytes,不能是strdata参数封装的两种情况如果是str型数据进行bytes(str,encoding)编码转成bytes类型如果是字典或恰含有两个元素的元组的数据通过urllib.parse.urlencode(data)转成str类型,再传入bytes.(str,encoding)方法转成bytes类型urlencode()方法详解见后文urllib.parse模块import urllib.request
import urllib.parse# 需要传入的data内容
data = {"name": "python"
}
# 将data进行转码
data = bytes(urllib.parse.urlencode(data),encoding='utf-8')
reponse = urllib.request.urlopen("",data = data)
print(reponse.read())
方法二:urllib.request.Request()实现post
Request(url, data=None, headers={}, origin_req_host=None, unverifiable=False, method=None)urllib.request.urlopen()方法可以实现最基本的请求的发起但如果要加入Headers等信息,就需要用Request类来构造请求正如前文提到data同样必须是bytes类型(only contain ASCII literal characters.)或者字典类型bytes传入时是做了数据字典的key,该key对应的value值为‘’headers必须是一个字典类型,加入headers的方法有两种(1)构造请求时通过headers参数直接构造传入(2)调用请求实例的add_header()方法添加(1)request实现post基本使用方法:不加入headers
req = urllib.request.Request(url='',data=b'Datawhale two') # 构建请求对象
with urllib.request.urlopen(req) as f:data=f.read()print(data.decode('utf-8'))运行结果
{"args": {},"data": "","files": {},"form": {"Datawhale": ""},"headers": {"Accept-Encoding": "identity","Content-Length": "9","Content-Type": "application/x-www-form-urlencoded","Host": "httpbin","User-Agent": "Python-urllib/3.7","X-Amzn-Trace-Id": "Root=1-5fb4b938-454a168f08baf6a960a1558b"},"json": null,"origin": "59.64.129.161","url": ""
}
结果显示默认"User-Agent":为"Python-urllib/3.7"from urllib import request, parse
url = ''
headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64)AppleWebKit/537.36 (KHTML,like Gecko) Chrome/86.0.4240.198 Safari/537.36','Host': 'httpbin'
}
dict = {'name': 'Germey'}
data = bytes(parse.urlencode(dict), encoding='utf8')
req = request.Request(url=url, data=data, headers=headers, method='POST')
response = request.urlopen(req)
print(response.read().decode('utf-8'))注意
header除了像上面那样通过参数传入,还可以通过Request对象的方法add_header()传入
req = request.Request(url=url,data=data,method='POST')
req.add_header('User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64)AppleWebKit/537.36 (KHTML,like Gecko) Chrome/86.0.4240.198 Safari/537.36',
'Host': 'httpbin')运行结果
{"args": {},"data": "","files": {},"form": {"name": "Germey"},"headers": {"Accept-Encoding": "identity","Content-Length": "11","Content-Type": "application/x-www-form-urlencoded","Host": "httpbin","User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64)AppleWebKit/537.36 (KHTML,like Gecko) Chrome/86.0.4240.198 Safari/537.36","X-Amzn-Trace-Id": "Root=1-5fb4b9d3-049174284be63d2126d26fe3"},"json": null,"origin": "59.64.129.161","url": ""
}

3、urlopen Request总结

(1)要添加header使用urllib.request.Request()
header必须是字典类型,通过参数传入或者add_header()方法添加

(2)要传入data使用post,data必须是bytes类型
dict字典类型通过urllib.parse.urlencode()先转str
str字符串类型通过bytes(str,encoding)转bytes

(3)urlopen()的url参数可以是str或者urllib.request.Request对象类型

(4) 读取的数据是bytes类型,通过bytes.decode()解码

(5)urllib.parse传送门()

(2)urlretrieve()实现网页下载文件/图片到本地

函数定义
urlretrieve(url, filename=None, reporthook=None, data=None)参数finename 指定了保存本地路径(若未指定,urllib会生成一个临时文件保存数据)reporthook 是一个回调函数,当连接上服务器、以及相应的数据块传输完毕时触发该回调可以利用这个回调函数来显示当前的下载进度 自定义的该函数需要三个参数(1)block_num:已经下载的数据块(2)block_size:数据块的大小(3)total_size:远程文件的大小	data 指 post 到服务器的数据返回值返回一个包含两个元素的(filename, headers)元组filename 表示保存到本地的路径,header 表示服务器的响应头

如下载python首页  
def Schedule(block_num, block_size, total_size):per = 100.0*float(block_num*block_size)/float(total_size)if per > 100:per = 100# print("block_num", block_num)# print("block_size", block_size)# print("total_size", total_size)print('{:.2f}%'.format(per))url = '/'
local = 'python.html'
filename, _ = urllib.request.urlretrieve(url, local, Schedule)
# ('python.html', <http.client.HTTPMessage object at 0x000001FD6491D6D8>)
print(filename)
# python.html运行结果
block_num 0
block_size 8192
total_size 49221
0.00%
block_num 1
block_size 8192
total_size 49221
16.64%
block_num 2
block_size 8192
total_size 49221
33.29%
block_num 3
block_size 8192
total_size 49221
49.93%
block_num 4
block_size 8192
total_size 49221
66.57%
block_num 5
block_size 8192
total_size 49221
83.22%
block_num 6
block_size 8192
total_size 49221
99.86%
block_num 7
block_size 8192
total_size 49221
100.00%
python.html

网页图片下载完全一样 只是图片url的获取不同:
方法一:通过chrome抓包工具element找

方法二:查看网页源代码ctrl+F匹配查找然后复制链接地址

另外下载网页上的某一个文件(图片),如
url= '.gif'下载本地后我们的文件命名
更通用的办法是采用字符串split方法
该方法返回一个列表,再采用列表切片[-1]获得url中最后一部分,即可作为本地的文件名
filename= url1.split('/')[-1]
另外注意 sys.stdout.write 和 print 的区别
如回调函数定义如下import sys
def _progress(block_num, block_size, total_size):per = float(block_num * block_size) / float(total_size) * 100.0if per >= 100:per = 100sys.stdout.write('\r>> Downloading %s %.1f%%' % (filename1, per))sys.stdout.flush()# print('\r>> Downloading %s %.1f%%' % (filename1, per))运行结果
Downloading python-logo.gif 100.0%如若将sys.stdout.write换成print()输出
输出
Downloading python-logo.gif 0.0%
Downloading python-logo.gif 100.0%二者的区别如下

sys.stdout.write是将str写到流,原封不动,不会像print那样默认end='\n'
sys.stdout.write只能输出一个str,而print能输出多个str,且默认sep=' '(一个空格)
print,默认flush=False.
print还可以直接把值写到file中print()调用时底层也是去调用sys.stdout.write(),然后再多输出一个换行
如 print('hello')=sys.stdout.write('hello\n')
即
sys.stdout.write(str)向缓冲区中写入内容将str写到流,原封不动,不会自动换行sys.stdout.flush()强制输出缓冲区的内容同时还要清空缓冲区正如我们之前学习文件中讲到
要向文件里输出字符串(或写文件f.write()),是先写进内存/缓冲区
(因为print默认flush=False,也没有手动执行flush的话)
在close文件之前直接打开文件是没有东西的,如果执行一个flush就有了

import time
import sys
for i in range(5):# print(i)sys.stdout.write(str(i))sys.stdout.flush()time.sleep(1)运行结果
每隔一秒输出一次
01234import time
import sys
for i in range(5):print(i)sys.stdout.flush()time.sleep(1)运行结果
每隔一秒输出一次
0
1
2
3
4

(3)ProxyHandler()处理器代理设置

快代理免费代理

上面的链接里包含几个免费的代理网站 不可访问就换代理ip 不稳定''该网站会返回一些请求的信息 诸如请求主机的ipimport urllib.request 
url = ''#接收参数是一个字典,ip需要指明端口号
hander = urllib.request.ProxyHandler({'http':'122.193.244.243:9999'})
opener = urllib.request.build_opener(handler)#方法一:open一个url
resp = opener.open(url)
print(resp.read())#方法二:open一个Request对象
request=urllib.request.Request(url)
resp = opener.open(request)#方法三:open一个Request对象,并设置opener为全局
request=urllib.request.Request(url)
urllib.request.install_opener(opener)
resp = urlopen(request)
print(resp.read())

更多推荐

urllib库(一)request模块:urlopen(),Request() 实现 get/post,urlretrieve() 下载网页文件,ProxyHa

本文发布于:2024-03-15 08:55:09,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1738526.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:模块   文件   下载网页   urlopen   urllib

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!