urllib模块的使用
urllib是python内置的HTTP请求库,无需安装即可使用,它包含了4个模块:
-
request:它是最基本的http请求模块,用来模拟浏览器发送请求
-
parse:一个工具模块,提供了许多URL处理方法,如:把URL字符串与URL组件的拆分和合并,或者字典(和js对象差不多)与URL字符串的相互转换
-
error:异常处理模块,如果请求发生错误可以捕捉致谢异常
-
robotparser:主要用来识别网站的robots.txt文件,然后判断哪些网站可以爬
1、urllib.request模块
-
urlopen()方法
用法例示:urllib.request.urlopen(url,data=None,[timeout])
此函数用于打开一个url,并返回一个文件对象,url为地址,data为参数,timeout为超时设置
该对象会返回一个HTTPResponse类型的对象,包含的方法和属性有:
- 方法:read()、readinto()、getheader(name)、getheaders()、fileno()
- 属性:msg、version、status、reason、bebuglevel、closed
import urllib.request import urllib.parse data = { "字典": "python中把{}叫做字典", "理解": "和js对象差不多", } # 使用urllib.parse把字典转为URL字符串,这样才可以成功发送请求 data = urllib.parse.urlencode(data).encode('utf-8') # 发送请求,data为参数,请求时间超过10秒后会报错,同时会返回一个HTTPResponse对象 response = urllib.request.urlopen('https://www.python.org',data=data,timeout=10) print(response.read().decode('utf-8')) # 返回网站内容 print(response.getheader('server')) # 返回像一头中的server值 print(response.getheaders()) # 以列表元祖对的形式返回响应头信息 print(response.fileno()) # 返回文件描述符 print(response.version) # 返回版本信息 print(response.status) # 返回状态码200,404代表网页未找到 print(response.debuglevel) # 返回调试等级 print(response.closed) # 返回对象是否关闭布尔值 print(response.geturl()) # 返回检索的URL print(response.info()) # 返回网页的头信息 print(response.getcode()) # 返回响应的HTTP状态码 print(response.msg) # 访问成功则返回ok print(response.reason) # 返回状态信息
-
Request()方法
用法例示:urllib.request.Request(url,data=None,headers={},origin_req_host=None,unverifiable=False,method=None)
此方法用于包装URL,可以添加请求头的信息
参数:
-
url:请求的URL,必须传递的参数,其他都是可选参数
-
data:上传的数据,必须传bytes字节流类型的数据,如果它是字典,可以先用urllib.parse模块里的urlencode()编码
-
headers:它是一个字典,主要是修改User_Agent头来伪装浏览器传递的是请求头数据,可以通过它构造请求头,也可以通过调用请求实例的方法add_header()来添加。可以直接复制http请求中的User_Agent属性
-
origin_req_host:指请求方的host名称或者IP地址
-
unverifiable:表示这个请求是否是无法验证的,默认为False,如我们请求一张图片如果没有权限获取图片那它的值就是true
-
method:是一个字符串,用来指示请求使用的方法,如:GET,POST,PUT等
import urllib.request import urllib.parse url = 'https://www.python.org' header = { 'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.163 Safari/537.36', 'Host':'localhost:8080' } data = urllib.parse.urlencode({'name':'tao'}).encode('utf-8') req = urllib.request.Request(url=url,data=data,headers=headers,method='POST') # req.add_header('User-Agent','Mozilla/5.0 (compatible; MSIE 8.4; Windows NT') # 也可以request的方法来添加 response = urllib.request.urlopen(req) print(response.read())
-
-
ProxyHandler()方法
- 用法例示:urllib.request.ProxyHandler({‘http’:‘192.168.1.1:8080’})
- 此函数用于设置发送请求代理IP,参数为一个对象,记录IP地址信息
import urllib.request import random iplist = [ {'http':'101.4.136.34:81'}, {'http':'39.137.69.7:8080'}, {'http':'39.137.95.74:80'}, {'http':'221.180.170.104:8080'} ] # 随机拿取代理IP proxy_support = urllib.request.ProxyHandler(random.choice(iplist)) # 创建一个实例化对象 opener = urllib.request.build_opener(proxy_support) # 将实例化对象设置为全局对象,可以理解为让urllib.request = opener urllib.request.install_opener(opener) # response = opener.urlopen(url)# 也可以直接通过opener对象发送请求,这样就不需要把对象设为全局 response = urllib.request.urlopen(url) print(response.read())
2、urllib.parse模块
-
urlparse()方法
-
用法例示:parse.urlparse(url=url,scheme=‘http’,allow_fragments=True)
-
该方法主要用于URL的识别与分段
from urllib import parse url = 'https://book.qidian.com/info/1004608738?wd=123&page=20#Catalog' """ url:待解析的url scheme='':假如解析的url没有协议,可以设置默认的协议,如果url有协议,设置此参数无效 allow_fragments=True:是否忽略锚点,默认为True表示不忽略,为False表示忽略 """ result = parse.urlparse(url=url,scheme='http',allow_fragments=True) print(result) print(result.scheme) """ (scheme='https', netloc='book.qidian.com', path='/info/1004608738', params='', query='wd=123&page=20', fragment='Catalog') scheme:表示协议 netloc:域名 path:路径 params:参数 query:查询条件,一般都是get请求的url fragment:锚点,用于直接定位页面的下拉位置,跳转到网页的指定位置 """
-
-
urlunparse()
- 用法示例: result = parse.urlunparse((‘协议’,‘域名’,‘路径’,‘参数’,‘查询条件’,‘锚点’))
- 该方法主要用于URL的组合,和上面相反
from urllin import parse url_parmas = ('https', 'book.qidian.com', '/info/1004608738', '', 'wd=123&page=20', 'Catalog') result = parse.urlunparse(url_parmas) print(result)
-
urlencode()方法
- 用法示例: parse.urlencode({‘字典’:‘111’})
- 该方法主要用于将字典构形式的参数序列化为url编码后的字符串
import urllib.request import urllib.parse data = { "字典": "python中把{}叫做字典", } # 使用urllib.parse把字典转为URL字符串,这样才可以成功发送请求 data = urllib.parse.urlencode(data).encode('utf-8') # 发送请求,data为参数,请求时间超过10秒后会报错,同时会返回一个HTTPResponse对象 response = urllib.request.urlopen('https://www.python.org',data=data,timeout=10)
-
quote()方法
- 用法示例: quote(‘中文’)
- 该方法主要用于将中文转换为URL编码格式
from urllib import parse word = '加油' print(parse.quote(word))
3、urllib.error模块
-
URLEerror类
URLError类来自urllib库的error模块,它继承自OSError类,是error异常模块的基类,由request模块产生的异常都可以通过捕获这个类来处理。from urllib import request,error try: response=request.urlopen('https://hehe.com/index') except error.URLError as e: print(e.reason)
-
HTTPError类
它是URLError的子类,专门用来处理HTTP请求错误,比如认证请求失败。from urllib import request,error try: responese = request.urlopen('https://hehe.com/index') except error.HTTPError as e: print(e.code)
-
URLError和HTTPError类一起使用
方案一:from urllib import request,error try: response = request.urlopen("http://www.bucunzai.com") # HTTPError是URLError的子类所以要放在前面 except error.HTTPError as e: print('HTTPError') print(e.code) except error.URLError as e: print('URLError') print(e.reason)
方案二:
from urllib import request,error try: response = urllib.request.urlopen(req) except urllib.error.URLError as e: # hasattr判断对象中是否有某个属性 if hasattr(e,'reason'): print('无法访问到目标服务器') print('错误为:', e.reason) elif hasattr(e, 'code'): print('服务器返回了错误信息') print('错误为:', e.code)
4、robotparser模块
robots协议(也称为爬虫协议、爬虫规则、机器人协议等)也就是robots.txt,网站通过robots协议告诉搜索引擎哪些页面可以抓取,哪些页面不能抓取。Robots协议是网站国际互联网界通行的道德规范,其目的是保护网站数据和敏感信息、确保用户个人信息和隐私不被侵犯。因其不是命令,故需要搜索引擎自觉遵守。