一、urllib库的基本用法-四个模块

urllib库-四个模块

urllib库常用有四个模块,常用前三个
urllib.request
urllib.error
urllib.parse
urllib.robotparser

一.urllib.request

urllib.request.urlopen()
urllib.request.Request()
handler

1.urlopen()

用于发送请求。
urllib.request.urlopen(url,data=None,[timeout,]*,cafile=None,capath=None,cadefault=False,context=None)

data:附加数据,如果传递了这个参数,它的请求方式就不再是GET,而是POST。

timeout:用于设置超时时间(s),如果请求超出了设置的这个时间,还没有得到响应,就会抛出异常。如果不指定该参数,就使用全局默认时间。

context:用来指定SSL设置。
cafile,capath分别指定CA证书和它的路径,在请求HTTPS链接时会有用。

import urllib.request
response=urllib.request.urlopen('https://baidu.com/')
print(response.read().decode('utf-8'))
print(type(response))
print(response.status)

……
<class ‘http.client.HTTPResponse’>
200

返回的response是一个HTTPResponse对象,
read()
getheaders()
getheader(name)
fileno()等方法,以及
msg,version,status,reason,debuglevel,closed等属性。

2.Request()

如果在请求中要加入Headers等信息,就要用更强大的Request类来构建。

urllib.request.Request(url,data=None,headers={},origin_req_host=None,unverifiable=False,method=None)

data必须是bytes(字节流)类型的。
headers是一个字典,就是请求头。可以在构造请求时通过headers参数直接构造,也可以通过请求实例的add_header()方法添加。
origin_req_host是请求方的host名称或者IP地址。

unverifiable表示这个请求是否是无法验证的,默认为False。
method是一个字符串,用来指示请求的方法:GET,POST,PUT等。

from urllib import request,parse
url='https://baidu.com/'
headers={'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64;x64)','HOST':'www.baidu.com'}
dict={'name':'Germey'}
data=bytes(parse.urlencode(dict),encoding='utf-8')
req=request.Request(url,data=data,headers=headers,method='POST')
response=request.urlopen(req)
print(response.read().decode('utf-8'))
print(type(response))

3.urllib.request中的BaseHandler类

它是所有其他Handler的父类。

HTTPDefaultErrorHandler:用于处理HTTP响应错误,错误都会抛出HTTPError异常。

二.urllib.error 处理异常

urllib的error模块定义了由request模块产生的异常。如果出现了问题,request模块就会抛出error模块中定义的异常。

1.URLError

URLError类来自urllib库的error模块,由request模块产生的异常都可以通过捕获这个类来处理。
属性reason,返回错误的原因

2.HTTPError

是URLError的子类,专门用来处理HTTP请求错误,比如认证请求失败。它有以下三个属性。
①code,返回HTTP状态码,比如404表示网页不存在,500表示服务器内部错误。
②reason,返回错误的原因。
③headers,返回请求头。
URLError是HTTPError的父类,可以先选择捕获子类的错误,再去捕获父类的错误。

from urllib import request,error
try:    
response=request.urlopen('https://baijiahao.baidu.com/s?id=1669902490677255322&wfr=spider&for=pc',timeout=0.01)    #print(response.read().decode('utf-8'))
except error.HTTPError as e:    
print(e.reason,e.code,e.headers,seq='\n')
except error.URLError as e:    
print(e.reason)
else:    
print('Request Successfully')

timed out

三.urllib.parse 解析链接

urllib库里的parse模块定义了处理url的标准接口。

1.urlparse()

urllib.parse.urlparse(urlstring,scheme=’’,allow_fragments=True)
urlsyring是待解析的url,scheme是默认的协议,比如http或者https等。allow_fragments,即是否忽略fragment。如果设置成False,fragment部分就会被忽略,它会被解析为path,parameters或者query的一部分,而fragment部分为空。

from urllib.parse import urlparse
result=urlparse('https://chaoshi.tmall.com/?targetPage=index&spm=a21bo.2017.201859.3.5af911d9qAM1Kd')
print(type(result),result)

<class ‘urllib.parse.ParseResult’>
ParseResult(scheme=‘https’, netloc=‘chaoshi.tmall.com’, path=’/’, params=’’, query=‘targetPage=index&spm=a21bo.2017.201859.3.5af911d9qAM1Kd’, fragment=’’)

urlparse()方法将其拆分成了6个部分。一个标准的链接格式如下:

scheme://netloc/path;params?query#fragement

协议,域名,路径,参数,查询条件,碎片。

①.如果链接没有带协议信息

from urllib.parse import urlparse
result=urlparse('chaoshi.tmall.com/?targetPage=index&spm=a21bo.2017.201859.3.5af911d9qAM1Kd',scheme='http')
print(result)

ParseResult(scheme=‘http’, netloc=’’, path=‘chaoshi.tmall.com/’, params=’’, query=‘targetPage=index&spm=a21bo.2017.201859.3.5af911d9qAM1Kd’, fragment=’’)

scheme参数只有在URL中不包含scheme信息时才生效。如果URL中有scheme信息,就会返回解析出的scheme。

②.allow_fragments参数
allow_fragments,即是否忽略fragment。如果设置成False,fragment部分就会被忽略,它会被解析为path,parameters或者query的一部分,而fragment部分为空。

2.urlunparse()

与urlparse()对立,接受的参数是一个可迭代对象,长度必须是6,否则会抛出参数数量不足或者过多的问题。

from urllib.parse import urlunparse
data=['http','www.baidu.com','index.html','user','a=6','comment']
print(urlunparse(data))

http://www.baidu.com/index.html;user?a=6#comment

data用了列表类型,也可以用其他类型,比如元组或者特定的数据结构。这样实现了URL的构造。

3.urlsplit()

类似urlparse(),只是它不再单独解析params这一部分,只返回5个结果。

from urllib.parse import urlsplit
result=urlsplit('http://www.baidu.com/index.html;user?id=5#comment')
print(result)
print(result.scheme,result[0])

SplitResult(scheme=‘http’, netloc=‘www.baidu.com’, path=’/index.html;user’, query=‘id=5’, fragment=‘comment’)
http http

返回结果是SplitResult,也是一个元组类型,可以用属性获取值,也可以用索引来获取。

4.urlunsplit()

和urlunparse()类似,是将链接各个部分组合成完整链接的方法。传入的参数要是一个可迭代对象,例如列表,元组,长度必须为5。

from urllib.parse import urlunsplit
data=['http','www.baidu.com','index.html','a=6','comment']
print(urlunsplit(data))

data中没有params。

http://www.baidu.com/index.html?a=6#comment

5.urljoin

提供一个base_url(基础链接)作为第一个参数,新的链接作为第二个参数。该方法徽分析base_url的scheme、netloc、path这三个内容并对新链缺失的部分进行补充,最后返回结果,实现链接的解析,拼合和生成。

from urllib.parse import urljoin
print(urljoin('http://www.baidu.com','FAQ.html'))
print(urljoin('http://www.baidu.com','https://hao360.com/FAQ.html'))
print(urljoin('http://www.baidu.com','?category=2#comment'))
print(urljoin('www.baidu.com','?category=2#comment'))

http://www.baidu.com/FAQ.html
https://hao360.com/FAQ.html
http://www.baidu.com?category=2#comment
www.baidu.com?category=2#comment

base_url里提供了三项内容:scheme,netloc,path,如果这三项在新的链接里不存在,就予以补充,如果新的链接存在,就使用新的链接部分。而base_url中的params,query,fragment是不起作用的。

6.urlencode

在构造GET请求参数非常有用。

from urllib.parse import urlencode
params={'name':'germey','age':'22'}
base_url='http://www.baidu.com?'
url=base_url+urlencode(params)
print(url)

http://www.baidu.com?name=germey&age=22

首先声明了一个字典将参数表示出来,调用urlencode()方法将其序列化为GET请求参数。

7.parse_qs()

反序列化
利用parse_qs()方法可以将一串GET请求参数转回字典。

from urllib.parse import parse_qs
query='name=germey&age=22'
print(parse_qs(query))

{‘name’: [‘germey’], ‘age’: [‘22’]}

可以看到,这样就成功转化为字典类型了。

8.parse_qsl()

将参数转化为元组组成的列表。

from urllib.parse import parse_qs,parse_qsl
query='name=germey&age=22'
print(parse_qs(query))
print(parse_qsl(query))

{‘name’: [‘germey’], ‘age’: [‘22’]}
[(‘name’, ‘germey’), (‘age’, ‘22’)]

运行结果是一个列表,而列表中的每一个元素是元组,元组的第一个内容是参数名,第二个内容是参数值。

9.quote()

该方法可以将内容转化为URL编码的格式。URL中带有中文参数时,有可能会导致乱码的问题,用这个方法可以将中文字符转化为URL编码

from urllib.parse import quote
keyword='壁纸'
url='https://www.baidu.com/s?wd='+quote(keyword)
print(url)

https://www.baidu.com/s?wd=%E5%A3%81%E7%BA%B8

10.unquote()

该方法可以进行URL解码。

from urllib.parse import quote,unquote
keyword='壁纸'
url='https://www.baidu.com/s?wd='+quote(keyword)
print(url)
print(unquote(url))

https://www.baidu.com/s?wd=%E5%A3%81%E7%BA%B8
https://www.baidu.com/s?wd=壁纸

四.分析Robots协议(urllib.robotparser)

1.Robots协议

Robots协议也称爬虫协议,机器人协议,用来告诉爬虫和搜索引擎哪些页面可以抓取,哪些不可以抓取。它通常是一个叫做robots.txt的文本文件,一般放在网站的根目录下。
爬虫访问一个站点,首先检查这个站点根目录下是否有robots.txt文件,若有,遵循这个文件定义的爬取范围来爬取;若没有,爬虫就会访问所有可直接访问的页面。
robots.txt样例

User-agent:*
Disallow:/
Allow:/public/

User-agent描述搜索爬虫的名称,*表示该协议对任何爬虫有效。
Disallow指定不允许抓取的目录,/表示不运行抓取所有页面。
Allow一般和Disallow一起使用。/public/表示不允许抓取所有页面,但是可以抓取public目录。

2.爬虫名称

爬虫是有固定名称的。
BaiduSpider百度
Googlebot谷歌
360Spider360搜索

3.robotparser

该模块提供了一个类RobotFileParser,它可以根据某网站的robots.txt文件判断一个爬取爬虫是否有权限来爬取这个网页。
urllib.robotparser.RobotFileParser(url=’’)

from urllib.robotparser import RobotFileParser
rp=RobotFileParser()
rp.set_url('http://www.jianshu.com/robots.txt')
rp.read()
print(rp.can_fetch('*','http://www.jianshu.com/p/b67554025d7d'))

False

①set_url()
用来设置robots.txt的链接,如果在创建RobotFileParser对象时传入了链接,那么就不需要这个方法设置。
②read()
读取robots.txt文件并进行分析。如果不调用这个方法,接下来的判断都会为False,这个方法不会返回任何内容,但是执行了读取操作。
③can_fetch()
该方法传入两个参数,第一个是User-agent,第二个是要抓取的URL,返回的是改搜索引擎是否可以抓取这个URL。

  • 0
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值