首页 > Web开发 > 详细

urllib库

时间:2019-12-22 17:49:31      阅读:118      评论:0      收藏:0      [点我收藏+]

urllib库 HTTP请求库

urllib 是一个用来处理网络请求的python标准库,它包含4个模块。
 urllib.requests 请求模块,用于发起网络请求
 urllib.parse 解析模块,用于解析URL
 urllib.error 异常处理模块,用于处理request引起的异常
 urllib.robotparse 用于解析robots.txt文件

一. request模块

1.urlopen方法 最基本的发送请求的方法,不支持添加请求头部

第一个参数时url 第二个参数时data 第三个参数是超时时间 !没有请求头headers参数

 import re
 import json
 import urllib3
 from urllib import request
 ?
 ?
 url = "http://httpbin.org/post"
 resp = request.urlopen(url=url, data=b"name=YeLan&age=20")
 print(resp.read().decode())    # 读取响应返回的数据,并且响应的数据只能读取一次
 print(readline()) # 读取一行,可以用循环读取全部
 print(resp.info())      # 获取响应头信息
 print(resp.geturl())    # 获取访问的url
 print(resp.getcode())   # 返回状态码
 ?
 # urlopen默认会发送get请求,当传入data参数时,则会发起POST请求。data参数是字节类型、类文件对象或可迭代对象。
 # data参数传输的是bytes类型的数据(一般以键值对的形式),以form表单的形式返回
 ?

 

Request对象

urlopen()方法不能添加请求头的参数headers因此需要更强大的Request对象

1.请求头添加

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

 from urllib import request
 ?
 ?
 url = ‘http://www.jianshu.com‘
 headers = {
     "User-Agent": "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) \
 Chrome/73.0.3683.86 Safari/537.36",
     "User-Agent": "Python-urllib/3.6" 默认的UA
 }
 referer = {"Referer": "http://httpbin.org"}
 # 如果请求头需要携带referer、content-type等,只需要将其更新至请求头即可
 headers.update(referer)
 ?
 req = request.Request(url, headers=headers) # 实例
 resp = request.urlopen(req) # 这里的urlopen() 接收一个Request对象也是可以的
 ?

 

Handler不同子类处理不同的需求

ProxyHandler 用于设置代理,默认代理为空

HTTPCookieProcessor 用于处理cookies

HTTPRedirectHandler 用于处理重定向

HTTPBasicAuthHandler 用于管理认证,若一个连接打开时需要认证,那么可以用他来解决认证问题

 

2.cookie操作

urlopen() 不支持代理、Cookie、https认证(auth); 因此我们需要借助底层的 Handler 处理器对象

 from urllib import request
 from http import cookiejar
 ?
 # 1.创建一个cookie对象
 cookie = cookiejar.CookieJar()
 ?
 # 2.创建一个cookie处理器
 handler = request.HTTPCookieProcessor(cookie)
 ?
 # 3.创建Opener对象, 将handler绑定到该对象
 opener = request.build_opener(handler)
 ?
 # 4.使用这个opener来发送请求(其实就是携带cookie)
 url = ‘http://www.baidu.com‘
 resp = opener.open(url)
 print(resp.info()) # 第一次请求时返回的响应头包含set-cookie
 resp = opener.open(url)
 print(resp.info()) # 第二次请求时返回的响应头不包含set-cookie;因为第二次请求时已经绑定了上一次请求的cookie了, 相当于浏览器已经认识你了
 ?
 resp = urlopen(url) # 而用urlopen()无论请求多少次,每次响应的头部都会有set-cookie,说明每次请求都没有携带上次的cookie
 print(resp.info) # 与opener.open()方法对比
3.设置代理

理解: 原理其实都是通过opener的open()方法发起请求

 from urllib.error import URLError
 ?
 url = ‘http://httpbin.org/ip‘
 # print(request.urlopen(url).read().decode()) # 该测试网址可以返回我们本机的网址
 # {"origin": "123.169.20.111, 123.169.20.111"}
 ?
 # 1.代理地址
 proxy = {
     ‘http‘: ‘221.6.32.206:41816‘,
     ‘https‘: ‘221.6.32.206:41816‘
 }
 # 2.创建代理处理器
 proxy_handler = request.ProxyHandler(proxy)
 # 3.创建opener对象 # 实质都是通过opener发起请求
 opener = request.build_opener(proxies)
 # 4.发送请求(如果代理ip被封,请求会出现异常)
 try:
     resp = opener.open(url)
     print(resp.read().decode()) # 返回代理ip
 except URLError as e:
  print(‘请求错误的原因:%s‘ % e.reason)
 ?

 

二、parse模块

parse模块是一个工具模块,提供了需要对url处理的方法,用于解析url。

parse模块常用方法: quote unquote urlencode parse_qs

url中只能包含ascii字符,在实际操作过程中,get请求通过url传递的参数中会有大量的特殊字符,例如汉字,那么就需要进行url编码。

 from urllib import parse, error, robotparser
 ?
 result = parse.quote("ie=UTF-8&wd=爬虫") # quote()只接受str类型 将url进行编码
 print(result)
 print(parse.unquote("%E7%88%AC%E8%99%AB")) # unquote 对url进行解码(反编码)
 ?
 params = {
     "wd": "爬虫",
     "username": "YeLan"
 }
 url = "https://www.baidu.com/s?"
 print(url + parse.urlencode(params)) # urlencode()接受字典;对url[url参数]进行编码
 param = parse.urlencode(params)
 print(parse.parse_qs(param)) # parse_qs()接收字典; 对url进行解码
 print(parse.parse_qs(‘wd=%E7%88%AC%E8%99%AB‘))
 ?
url = urljoin(‘https:‘, ‘//ke.qq.com/course‘) # 该方法用来拼接url
===> url = "https://ke.qq.com/course"

三、urllib.error模块

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

主要包含URLError和HTTPError

 URLError:是error异常模块的基类,由request模块产生的异常都可以用这个类来处理
 该异常常用属性: reason 错误的原因
 ?
 HTTPError:是URLError的子类,主要包含三个属性:
 Code:请求的状态码
 reason:错误的原因
 headers:响应的报头
 ?

 

四、urllib.robotparse模块

该模块的 RobotFileparser(url=‘www.baidu.com/robot.txt‘)用来解析robot文件(了解就行)

 Robots协议(也称为爬虫协议、机器人协议等)的全称是“网络爬虫排除标准”(Robots Exclusion Protocol),网站通过Robots协议告诉搜索引擎哪些页面可以抓取,哪些页面不能抓取。
 ?
 https://www.baidu.com/robots.txt
 https://www.taobao.com/robots.txt
 ?
 robots.txt文件是一个文本文件, robots.txt是一个协议,而不是一个命令.

 

urllib3 第三方HTTP库

安装: pip install urllib3

urllib3.disable_warnings() 禁用警告信息

一、基本使用

import urllib3

url = ‘http://image.baidu.com‘
headers = {
    "User-Agent":"Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.86 Safari/537.36",
    "Referer":"https://www.baidu.com"
} 

# 实例一个PoolManager对象构造请求。该对象处理了连接池和线程安全的所有细节,所以我们不用自行处理
http = urllib3.PoolManager()		

# 1. 发送get请求
resp = http.request(‘GET‘, url, headers=headers)
print(resp.data.decode("utf-8"))	# 解码为文本html
# 响应属性
print(resp.data)			# 返回的是二进制数据
print(resp.status)			# 响应状态码
print(resp.headers)			# 响应头

print(resp.getheaders())	# 方法:获取响应头部信息
print(resp.info())			# 方法:响应头部信息

# 2. 发送post请求
form_data = {
    ‘username‘: ‘yelan‘,
    ‘password‘: ‘wwxxxx‘
}
resp = http.request(‘post‘, ‘http://httpbin.org/post‘, fields=form_data)	# fields参数就是post请求提交的数据(form表单)

# 3. 大文件下载	# 修改可选参数preload_content=False 以流的形式下载
http = urllib3.PoolManager(headers=headers)		# 创建该对象时,就指定headers后续请求都会携带请求头
resp = http.request(‘get‘, http://httpbin.org/bytes/102400, preload_content=False)
for chunk in resp.stream(128):		# 每次读取128字节
	print(chunk)
    
# 4. 文件上传(注意上传文件是二进制数据,使用body参数接收,与提交数据区分)
with open(r"../img/img_1.jpg","rb") as fb:
    binary_data = fb.read()
    
headers.update({‘Content-Type‘:‘image/jpeg‘})	# 上传文件|携带json等需要指定类型
response = http.request("POST", ‘http://httpbin.org/post‘, body=binary_data, headers=headers)
print(json.loads(response.data.decode("utf-8")))

 

request参数:
method: <str> 请求方法
url:	<str> 请求url
headers	<dict> 请求头
fields	<dict> 发送get请求时该参数就是url的参数, 而当发送post请求时,该参数就是提交的数据(如form表单)
body	<bytes> 发送post请求携带的二进制数据;如请求时携带json数据或者上传文件。
preload_content	<bool>	默认为True, 修改为False时以流的形式接收数据。

 

import urllib3

# 若我们会发送多个请求,那么给每个请求都去写headers=headers这样太重复了;所以可以在创建该对象时,就指定headers,则后续请求都会携带请求头。
http = urllib3.PoolManager(headers=headers)	

# 1.如果我们GET请求要发送URL参数, 那么怎么发送呢? 那么给fields参数传入包含了URL参数数据的字典即可.
resp = http.request("GET", url="https://httpbin.org/get", fields={"name": "jack", "age": "18"})
print(resp.data.decode())

# 2.若POST请求也要携带URL参数, 怎么办呢? 也是fields? 不是!要通过构造URL才发送URL参数.而fields参数是以字典的形式携带的表单数据
url = "https://httpbin.org/post?name=jack&age=18"
resp = http.request("POST", url=url, fields=form_data)
print(resp.data.decode())       		# str类型的键值对即json数据类型
print(json.loads(resp.data.decode()))   # json转python字典

 

http代理
url = ‘http://httpbin.org/get‘
pro_host = "http://221.6.32.206:41816"
# 1. 创建一个代理对象
proxy = urllib3.ProxyManager(proxy_url=pro_host, headers=headers, proxy_headers=None)
# 2. 基于该代理对象发送请求
resp = proxy.request("get", url=url, headers=headers)
print(resp.data.decode())

 

对于post和put请求,如果需要查询参数,需要通过url编码将参数编码成正确格式然后拼接到url中
import urllib3
from urllib import parse

args = {
    "user": "YeLan",
    "key": "value",
}
form_data = {
    "user": "yelan",
    "pwd": "123456"
}
args_encoded = parse.urlencode(args)
url = ‘http://httpbin.org/post?‘ + args_encoded
http = urllib3.PoolManager(headers=headers)

resp = http.request("POST", url)
print(json.loads(resp.data.decode())["args"])   # 返回的字典是无序的

# Form data :对于put和post请求,需要提供字典类型的参数field来传递form表单数据。
resp = http.request("POST", url=url, fields=form_data)
print(json.loads(resp.data.decode())["form"])

 

请求时携带json数据; 通过body参数携带二进制的json数据,并指定请求头的content_type
data = {
    "user":"YeLan",
    "key":"value",
    "age":"22"
}
json_data_encoded = json.dumps(data).encode("utf-8") # 将dict转化为json数据再编码
content_type = {
    ‘Content-Type‘: ‘application/json‘
}
headers = header.update(content_type)     # 更新头部信息

# JSON 当我们需要发送json数据时,我们需要在request中传入编码后的二进制数据类型的body参数,并指定Content—Type的请求头
url = "http://httpbin.org/post"
http = urllib3.PoolManager()
resp = http.request("POST", url=url, body=json_data_encoded, headers=headers)
print(json.loads(resp.data.decode()))

 

 

爬虫开发流程

1.找到目标数据
2.分析请求流程
3.构造http请求
4.提取清洗数据
5.数据持久化

 

 

urllib库

原文:https://www.cnblogs.com/yelan5222/p/12080243.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!