python3 中使用urllib问题以及urllib详解
今天遇到一个蛮奇怪的问题:当我在控制台中使用urllib没问题,但是当我在vscode中.py文件中导入urllib使用时会报错:
AttributeError:module'urllib'hasnoattribute'request'
查了一下资料是python3的urllib不会自动导入其under层的包,需要手动导入。
importurllib importurllib.parse importurllib.request
再次使用即可成功。
urllibe是python3中将中文urlencode编码使用的函数,urlencode使用如下:
importurllib importurllib.parse urllib.parse.quote(string,safe='/',encoding=None,errors=None)
urllib将编码后的字符串转为中文则使用:
importurllib importurllib.parse urllib.parse.unquote(string,encoding='utf-8',errors='replace')
聊到这里就顺带讲讲urllibe的使用吧
urllib是一个python内置包,不需要额外安装即可使用,它包含一下几个用来处理url的模版。
- urllib.request,用来打开和读取url,意思就是可以用它来模拟发送请求,就像在浏览器里输入网址然后敲击回车一样,获取网页响应内容。
- urllib.error,用来处理urllib.request引起的异常,保证程序的正常执行。
- urllib.parse,用来解析url,可以对url进行拆分、合并等。
- urllib.robotparse,用来解析robots.txt文件,判断网站是否能够进行爬取。
urllib.request模块
urllib.request模块定义了以下几个函数。
urllib.request.urlopen(url,data=None,[timeout,]*,cafile=None,capath=None,cadefault=False,context=None)
该函数主要用于模拟网站请求,返回一个HTTPResponse类型的对象。
urlopen函数中参数定义
- url,必选参数,是一个str字符串或者Request对象(后面会介绍)。
- data,bytes类型的可选参数,如果传递的是字典型数据,可以用urllib.parse.urlencode()进行编码,返回str字符串,再将str转换成bytes字节流。如果传递data参数,urlopen将使用HTTPPOST方式请求,否则为HTTPGET请求。
- timeout,可选参数,设置超时时间(未设置时使用全局默认超时时间),以秒为单位计时,如果urlopen请求超出了设置时间还未得到响应则抛出异常。
- cafile和capath,可选参数,在HTTPS连接请求时指定已认证的CA证书以及证书路径。
- cadefault,一般可忽略该参数。
- context,ssl.SSLContext类型的可选参数,用来指定SSL设置。
urlopen函数返回类型
urlopen函数请求返回一个HTTPResponse响应上下文,或者请求异常抛出URLError协议错误,一般有如下属性:
- geturl(),返回检索的url,通常用于判定是否进行了重定向。
- info(),返回网页的头信息。
- getcode(),返回HTTPResponse响应的状态码。
urlopen函数的应用实例
#创建一个HTTPGET请求,输出响应上下文 fromurllib.requestimporturlopen response=urlopen("http://www.python.org") print(response.read()) #创建一个HTTPPOST请求,输出响应上下文 fromurllib.requestimporturlopen fromurllib.parseimporturlencode data={'kw':'python'} data=bytes(urlencode(data),encoding='utf-8') response=urlopen("https://fanyi.baidu.com/sug",data) print(response.read().decode('unicode_escape'))
urllib.request.Request(url,data=None,headers={},origin_req_host=None,unverifiable=False,method=None)
该函数主要用于构造一个url,返回一个urllib.request.Request对象。
Request函数中参数定义
- url,必选参数,请求的url地址。
- data,bytes类型的可选参数。
- headers,字典类型,有些HTTP服务器仅允许来自浏览器的请求,因此通过headers来模拟浏览器对url的访问,比如模拟谷歌浏览器时使用的headers:”Mozilla/5.0(WindowsNT6.1;Win64;x64)AppleWebKit/537.36(KHTML,likeGecko)Chrome/76.0.3809.132Safari/537.36”。可以通过调用add_header()来添加headers信息。
- origin_req_host,请求方的host名称或者IP地址。
- unverifiable,表示这个请求是否无法验证,默认为False。比如请求一张图片,如果没有权限获取图片那它的值就是true。
- method,是一个字符串,用来指示请求使用的方法,如:GET,POST,PUT等,默认是GET请求。
Request函数返回类型
与urlopen函数请求返回一样,一般返回一个HTTPResponse响应上下文。
Request函数的应用实例
#采用HTTPGET请求的方法模拟谷歌浏览器访问网站,输出响应上下文 fromurllibimportrequest,parse url='http://www.python.org' headers={'User-Agent':'Mozilla/5.0(WindowsNT6.1;Win64;x64)AppleWebKit/537.36(KHTML,likeGecko)Chrome/76.0.3809.132Safari/537.36' } req=request.Request(url,headers=headers,method='GET') response=request.urlopen(req) print(response.read())
2urllib.error模块
urllib.error模块定义了由urllib.request模块引发的异常,异常主要包含URLError和HTTPError。
urllib.error.URLError异常
URLError类继承自OSError类,是error异常模块的基类,由request模块产生的异常都可以通过捕获这个类来处理。URLError只有一个属性reason,即返回错误的原因。
应用实例:
#在请求连接时候捕获网址错误引发的异常 fromurllibimportrequest,error try:response=request.urlopen('https://www,baidu,com') excepterror.URLErrorase:print(e.reason)
urllib.error.HTTPError异常
HTTPError是URLError的子类,专门用来处理HTTP请求错误,比如认证请求失败,包含以下三个属性:
- code:返回HTTP响应的状态码,如404页面不存在等。
- reason:返回错误的原因。
- headers:返回HTTP响应头信息。
应用举例:
#返回401未授权错误 fromurllibimportrequest,error try:response=request.urlopen('http://pythonscraping.com/pages/auth/login.php')print(response.getcode()) excepterror.HTTPErrorase:print('1.错误原因:\n%s\n2.状态码:\n%s\n3.响应头信息:\n%s'%(e.reason,e.code,e.headers)) excepterror.URLErrorase:print(e.reason)
urllib.parse模块
urllib.parse模块定义了一个处理url的标准接口,用来实现url字符串的抽取、合并以及链接转换。该模块主要用到的函数如下。
urllib.parse.urlparse(urlstring,scheme='',allow_fragments=True)
用于实现url字符串的识别和分段,可以分为六个字符串,分别是scheme(协议),netloc(域名),path(路径),params(参数),query(查询条件)和fragment(锚点),其结构如下所示:“scheme://netloc/path;parameters?query#fragment”。实际上具体url某些字段可能会不存在,比如“http://www.baidu.com”只包含了协议和域名。
urlparse函数中参数定义
- urlstring,待解析的url字符串。
- scheme,是默认的协议,比如http或者https,url字符串中如果不携带相关协议,可以通过scheme来指定,如果url中指定了相关协议则在url中生效。
- allow_fragments,是否忽略锚点,设置为False即fragment部分会被忽略,反之不会忽略。
urlparse的返回类型
函数返回的是一个urllib.parse.ParseResult对象,获取解析出来的url六个字段。
urlparse应用举例
#解析并输出url中每个字段的字符串 importurllib url='http://www.baidu.com/urllib.parse.html;python?kw=urllib.parse#module-urllib' result=urllib.parse.urlparse(url) print(result) print(result.scheme,result.netloc,result.path,result.params,result.query,result.fragment,sep='\n')
urllib.parse.urlunparse(parts)
与urlparse相反,通过列表或者元祖的形式将分段的字符串组合成一个完整的url字符串。
urlunparse函数中参数定义
parts,可以是列表或者元组。
urlunparse的返回类型
urlunparse函数返回一个构造好的url字符串。
应用举例
#通过data列表或元组构造一个url并输出 importurllib dataList=['http','www.baidu.com','/urllib.parse.html','python','kw=urllib.parse','modul-urllib']#六个字符串都必须填写,否则会出现ValueError错误,如果某一字符串不存在则填入空字符 dataTuple=('http','www.baidu.com','/urllib.parse.html','','kw=urllib.parse','modul-urllib')#六个字符串都必须填写,否则会出现ValueError错误,如果某一字符串不存在则填入空字符 urlList=urllib.parse.urlunparse(dataList) urlTuple=urllib.parse.urlunparse(dataTuple) print('1.urlList:%s\n2.urlTuple:%s'%(urlList,urlTuple))
urllib.parse.urlsplit(urlstring,scheme='',allow_fragments=True)
与urlparse函数类似,但它只返回url字符串的5个字段,把params合并到path中。
urlsplit应用举例
#解析并输出url中每个字段的字符串,params会合并到path中。 importurllib url='http://www.baidu.com/urllib.parse.html;python?kw=urllib.parse#modul-urllib' result=urllib.parse.urlsplit(url) print(result) print(result.scheme,result.netloc,result.path,result.query,result.fragment,sep='\n')
urllib.parse.urlunsplit(parts)
与urlunparse函数类似,它也是将url中各部分字段组合完整的url字符串的方法,唯一的区别是列表或元组的长度必须是5个,因为它把params省略了。
urlunsplit应用举例
#通过data列表或元组构造一个url并输出 importurllib dataList=['http','www.baidu.com','/urllib.parse.html;python','kw=urllib.parse','modul-urllib']#五个字符串都必须填写,否则会出现ValueError错误,如果某一字符串不存在则填入空字符 dataTuple=('http','www.baidu.com','/urllib.parse.html;python','kw=urllib.parse','modul-urllib')#五个字符串都必须填写,否则会出现ValueError错误,如果某一字符串不存在则填入空字符 urlList=urllib.parse.urlunsplit(dataList) urlTuple=urllib.parse.urlunsplit(dataTuple) print('1.urlList:%s\n2.urlTuple:%s'%(urlList,urlTuple))
urllib.parse.quote(string,safe='/',encoding=None,errors=None)
使用%xx转义字符替换字符串中的特殊字符,比如汉字。字母、数字和‘_.-~'字符不会被替换。
quote函数中参数定义
- string,可以是str字符串或bytes类型。
- safe,可选参数,默认是'/',指明不应该被替换的附加ASCII字符。
- encoding和errors,可选参数,用来定义如何处理non-ASCII字符。一般默认设置编码方法为encoding='utf-8',errors='strict',这意味着编码错误将引发UnicodeError。如果string是bytes类型,不能设置encoding和errors,否则将引发TypeError。
quote函数的返回类型
quote函数返回一个编码后的字符串。
应用举例
#采用quote对url中的汉字进行编码,输出编码后的结果 importurllib url='http://www.baidu.com/爬虫' result=urllib.parse.quote(url) print(result) url='http://www.baidu.com/+爬虫' result=urllib.parse.quote(url,'+')#更改safe参数 print(result)
urllib.parse.unquote(string,encoding='utf-8',errors='replace')
与quote函数相反,把%xx转义字符替换成字符。
- unquote函数的参数定义
- string,必须是str字符串。
- encoding和errors,可选参数,定义如何将%xx转义字符解码为Unicode字符。encoding默认为‘utf-8',errors默认为‘replace',表示无效的转义字符将会用占位符替换。
unquote函数的返回类型
unquote函数返回一个解码后的字符串。
应用举例
#解码经过quote函数处理后的url,输出解码后的结果。 importurllib url='http://www.baidu.com/爬虫' result=urllib.parse.quote(url) print(result) result=urllib.parse.unquote(url) print(result)
urllib.parse.urljoin(base,url,allow_fragments=True)
该函数用来将基本url与另一个url组合,更新基本url字符串。它会使用url对基本url中缺失的部分进行补充,比如scheme(协议)、netloc(域名)和path(路径)。即根据url字符串中带有的字段,对基本url中没有的字段进行补充,已存在的字段进行替换。
- urljoin函数中参数定义
- base,是一个基本url。
- url,将scheme(协议)、netloc(域名)或path(路径)字段组合进基本url的url。
- allow_fragments,是否忽略锚点,设置为False即fragment部分会被忽略,反之不会忽略。
urljoin函数返回类型
返回组合成功的url字符串。
应用举例
#基于url对base_url进行重新组合,并输出组合结果。 importurllib base_url='http://www.baidu.com' url='https://www.google.com/urllib.parse.html;python?kw=urllib.parse#module-urllib' result=urllib.parse.urljoin(base_url,url,False) print(result)
urllib.parse.urlencode(query,doseq=False,safe='',encoding=None,errors=None,quote_via=quote_plus)
urlencode函数可以将字典转化为GET请求中的query(查询条件),或者将字典转化为POST请求中需要上传的数据。
- urlencode函数中参数定义
- query,字典类型。
- doseq,允许字典中一个键对应多个值,编码成query(查询条件)。
- safe、encoding和errors,这三个参数由quote_via指定。
urlencode函数返回类型
urlencode函数返回str字符串。
应用举例
#创建GET请求 importurllib params={'username':'xxx','password':'123'} base_url='http://www.baidu.com' url=base_url+'?'+urllib.parse.urlencode(params) print(url) params={'username':['xxx','yyy'],'password':'123'}#username键对应多个值 base_url='http://www.baidu.com' url=base_url+'?'+urllib.parse.urlencode(params)#doseq设置为False,会解析成乱码 print(url) url=base_url+'?'+urllib.parse.urlencode(params,True)#doseq设置为True print(url)
urllib.robotparse模块
rebotparser模块提供了一个RobotFileParser类,主要用来解析网站上发布的robots.txt,然后根据解析内容判断爬虫是否有权限来爬取这个网页。
robots.txt文件
robots.txt,存放于网站根目录下,采用ASCII编码的文本文件,记录此网站中的哪些内容是不应被爬虫获取的,哪些是可以被爬虫获取的。
robots.txt文件内容举例
User-agent:*Disallow:/Allow:/public/
- User-agent,爬虫的名称,将其设置为*代表协议对任何爬虫有效,如果设置为Baiduspider则代表协议仅对百度爬虫有效,要是有多条则对多个爬虫有效,至少需要指定一条。
- Disallow,网页中不允许抓取的目录,上述例子中设置的/代表不允许抓取所有的页面。
- Allow,一般和Disallow一起使用,用来排除单独的某些限制,上述例子中设置为/public/表示所有页面不允许抓取,但可以抓取public目录。
urllib.robotparser.RobotFileParser(url='')类及其常用方法
- set_url(url),设置引用robots.txt文件的url,如果在创建RobotFileParser对象时传入了url,那么就不需要使用这个方法设置url。
- read(),读取robots.txt文件并将其提供给解析器,不返回任何内容。
- parse(lines),用来解析robots.txt某些行的内容,并安装语法规则来分析内容。
- can_fetch(useragent,url),传入两个参数,用户代理以及要爬取的网站,返回的内容是该用户代理否可以抓取这个网站,结果为True或False。
到此这篇关于python3中使用urllib问题以及urllib详解的文章就介绍到这了,更多相关python3使用urllib内容请搜索毛票票以前的文章或继续浏览下面的相关文章希望大家以后多多支持毛票票!