如何使用urllib和urllib3构建长尾词查询的HTTP客户端?

2026-04-13 10:052阅读0评论SEO资源
  • 内容介绍
  • 文章标签
  • 相关推荐

本文共计3738个文字,预计阅读时间需要15分钟。

如何使用urllib和urllib3构建长尾词查询的HTTP客户端?

一、urllib概述:urllib是Python中用于请求URL连接的官方标准库。当你安装了Python,这个库就已经可用,无需额外安装。它提供了基本的网络请求功能,涵盖了如GET、POST等基本的HTTP请求方法。在Python 2中,主要使用urllib和urllib2。

一、urllib概述:

urllib是Python中请求url连接的官方标准库,就是你安装了python,这个库就已经可以直接使用了,基本上涵盖了基础的网络请求功能。在Python2中主要为urllib和urllib2,在Python3中整合成了urllib。

Python3.x中将urllib2合并到了urllib,之后此包分成了以下四个模块:

  • urllib.request: 它是最基本的www.baidu.com" parsed = urllib.parse.urlparse(url) print(parsed) # 输出:ParseResult(scheme='www.baidu.com/index.html;user?a=6#comment2、urlsplit()、urlunsplit():URL分割与组合

    与urlparse()方法类似,它会返回5个部分,只是把params合并到path中。

    from urllib.parse import urlsplit result = urlsplit('www.baidu.com/index.html;user?id=5#comment') print(result) print(result.query) # output # SplitResult(scheme='www.baidu.com/index.html?a=5#comment3、urlencode()、parse_qs():查询字符串与字典类型转换

    urlencode() 将dict中的键值对以连接符&划分。

    urlencode()在构造GET请求参数时很有用,可以将字典类型的请求数据转变为url编码

    import urllib.parse dic = {'name':'melon','age':18} data = urllib.parse.urlencode(dic) print(data) #age=18&name=melon

    parse_qs()与urlencode()正好相反,它是用来反序列化的,如将GET参数转换回字典格式

    from urllib.parse import urlencode,parse_qs,urlsplit params = {'username':'zs','password':'123'} base_url='www.baidu.com' url=base_url+'?'+urlencode(params) #将字典转化为get参数 query=urlsplit(url).query #获去URL的query参数条件 print(parse_qs(query)) #根据获取的GET参数转换为字典格式 #output #{'username': ['zs'], 'password': ['123']}4、quote()、unquote():URL编码与解码

    quote:URL编码处理,该方法可以将内容转换为URL编码的格式。

    如参数中带有中文等非ASCII码时,有时会导致乱码的问题,此时用这个方法将中文字符转化为URL编码

    from urllib.parse import quote key='中文' url='www.baidu.com/s?key='+quote(key) print(url) #output #www.baidu.com/s?key=%E4%B8%AD%E6%96%87

    unquote(url):URL解码处理,与quote()相反,URL上的特殊字符还原

    from urllib.parse import quote, urlsplit, unquote key = '中文' url = 'www.baidu.com/s?key=' + quote(key) print(url) unq = urlsplit(url).query.split('=')[1] # 获取参数值 print(unquote(unq)) # 解码参数5、urljoin():将url的根域名和新url拼合成一个完整的url

    格式:urljoin(baseurl,newurl,allowFrag=None)

    通过将基本URL(base)与另一个URL(url)组合起来构建完整URL,它会使用基本URL组件,协议(schemm)、域名(netloc)、路径(path)、来提供给URL中缺失的部分进行补充,最后返回结果。

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

    通过urljoin()方法可以实现链接的解析、拼接和生成。

    import urllib.parse url = "www.baidu.com" new_path = urllib.parse.urljoin(url, "index.html") print(new_path) # 输出:<a href="www.baidu.com/index.html" rel="external nofollow" target="_blank">www.baidu.com/index.html</a>三、urllib.request模块1、urlretrieve():下载url到html文件。

    urlretrieve(url,filename,reporthook,data)

    不写路径filename则会被存为临时文件,可以用 urllib.urlcleanup() 来清理缓存

    file_name = urllib.request.urlretrieve('www.baidu.com','%s/baidu.html'%BASE_DIR)2、urlopen():打开一个url的方法,返回一个文件对象,然后可以进行类似文件对象的操作

    模块中最常用的函数为urlopen():

    urllib.request.urlopen(url, data=None, [timeout, ]*, cafile=None, capath=None, cadefault=False, context=None)

    参数如下:

    • url: 请求的网址,str类型,也可以是一个request对象

    • data:要发送到服务器的数据,data参数是可选的,内容为字节流编码格式的即bytes类型,如果传递data参数,urlopen将使用Post方式请求。

    • timeout:设置网站的访问超时时间,单位为秒,如果请求超出了设置时间还未得到响应则抛出异常,支持HTTP,HTTPS,FTP请求。

    • 其他参数:context参数,她必须是ssl.SSLContext类型,用来指定SSL设置,此外,cafile和capath这两个参数分别指定CA证书和它的路径,会在www.baidu.com') print(req.read().decode()) print(req.getheaders()) # 以列表元祖对的形式返回响应头信息 print(req.getheader('Content-Type')) # 返回响应头中的Content-Type值 print(req.info()) # 返回网页的头信息 print(req.info()['Content-Type']) # 返回响应头中的Content-Type值2、for循环读取

      不需要使用read()方法 。

      for line in urlopen('。。.html'): line = line.decode('utf-8') # Decoding the binary data to text. if 'EST' in line or 'EDT' in line: # look for Eastern Time print(line)3、GET请求

      GET请求和我们平常get访问方式一样,直接把参数写到网址上面就好了。

      import urllib.request import urllib.parse dic = {'name':'melon','age':18} data = urllib.parse.urlencode(dic) req = urllib.request.urlopen('127.0.0.1:8000/index?%s'%data) #通过urlopen方法访问拼接好的url content = req.read()4、POST请求

      urlopen()方法中,urlopen()默认的访问方式是GET,当在urlopen()方法中传入data参数时,则会发起POST请求。

      注意:传递的data数据需要为bytes格式,如data=b'word=hello'。

      import urllib.request import urllib.parse import json dic = {'name':'melon','age':18} data = urllib.parse.urlencode(dic) req = urllib.request.Request('127.0.0.1:8000/index', data.encode()) #encode:将url编码类型的请求数据转变为bytes类型 opener = urllib.request.urlopen(req) content = json.loads(opener.read().decode()) #read()方法是读取返回bytes数据内容,decode转换后为str5、请求头参数模拟

      当我们需要模拟一些其他的参数的时候,简单的urlopen() 方法已经无法满足我们的需求了,这个时候我们就需要使用下面的urllib.request中的Request对象来帮助我们实现一些其它参数的模拟,比如请求头。

      Request对象如下所示:

      如何使用urllib和urllib3构建长尾词查询的HTTP客户端?

      # Request对象实例化 req = urllib.request.Request(url, data=None, headers={},origin_req_host=None,unverifiable=False, method=None)

      • url:请求的URL,必须传递的参数,其他都是可选参数

      • data:上传的数据,必须传bytes字节流类型的数据,如果它是字典,可以先用urllib.parse模块里的urlencode()编码

      • headers:它是一个字典,传递的是请求头数据,可以通过它构造请求头,也可以通过调用请求实例的方法add_header()来添加
        例如:修改User_Agent头的值来伪装浏览器,比如火狐浏览器可以这样设置:
        {'User-Agent':'Mozilla/5.0 (compatible; MSIE 5.5; Windows NT)'}

      • origin_req_host:指请求方的host名称或者IP地址

      • unverifiable:表示这个请求是否是无法验证的,默认为False,如我们请求一张图片如果没有权限获取图片那它的值就是true

      • method:是一个字符串,用来指示请求使用的方法,如:GET,POST,PUT等

      from urllib import request url='localhost' p=HTTPPasswordMgrWithDefaultRealm() #构造密码管理实例 p.add_password(None,url,username,passowrd) #添加用户名和密码到实例中 auth_handler=HTTPBasicAuthHandler(p) #传递密码管理实例构建一个验证实例 opener=build_opener(auth_handler) #构建一个Opener try: result=opener.open(url) #打开链接,完成验证,返回的结果是验证后的页面内容 html=result.read().decode('utf-8') print(html) except URLError as e: print(e.reason)2、设置Proxy代理:ProxyHandler

      使用爬虫来爬取数据的时候,如果过于频繁的访问,而且网站还设有限制的话,很有可能会禁封我们的ip地址,这个时候就需要设置代理,来隐藏我们的真实IP。

      urllib提供了urllib.request.ProxyHandler()方法可动态的设置代理IP池。将代理IP以字典形式传入该方法,然后通过urllib.reques.build_opener()创建opener对象,用该对象的open()方法向服务器发送请求。

      from urllib import request url = 'www.baidu.com') # 使用这个opener来发起请求 # 查看之前的cookie对象,则可以看到访问百度获得的cookie for i in cookie: print(i)

      cookies保存到文件:

      1、以Mozilla型浏览器的cookies格式:

      cookie=www.baidu.com') #请求 cookie.save(ignore_discard=True,ignore_expires=True)

      从文件中读取cookies:

      2、也可以保存为libwww-perl(LWP)格式的Cookies文件

      cookie=www.baidu.com') #请求 print(response.read().decode('utf-8'))

      当然,如果把上面这个生成的opener对象使用install_opener方法来设置为全局的,opener对象之后的每次访问都会带上这个cookie。

      4、证书验证

      通过添加忽略ssl证书验证关闭证书验证,由于urllib并没有很好的处理ssl的对象,所以在这里我们需要用到一个别的库,即ssl库,如下:

      import ssl from urllib import request context = ssl._create_unverified_context() res = urllib.request.urlopen(request, context=context)

      当你 urllib.urlopen一个 hehe,com/index') except error.URLError as e: print(e.reason) #如果网页不存在不会抛出异常,而是返回捕获的异常错误的原因(Not Found)

      reason如超时则返回一个对象

      import socket import urllib.request import urllib.error try: response=urllib.request.urlopen('www.baidu.com',timeout=0.001) except urllib.error.URLError as e: print(e.reason) if isinstance(e.reason,socket.timeout): print('time out')2、HTTPError

      它是URLError的子类,专门用来处理HTTP请求错误,比如认证请求失败,它有3个属性:

      • code:返回HTTP的状态码,如404页面不存在,500服务器错误等

      • reason:同父类,返回错误的原因

      • headers:返回请求头

      举例:

      from urllib import request,error try: response=request.urlopen('cuiqingcai.com/index.htm') except error.HTTPError as e: #先捕获子类异常 print(e.reason,e.code,e.headers,sep='\n') except error.URLError as e: #再捕获父类异常 print(e.reason) else: print('request successfully')五、urllib.robotparser模块

      利用urllib的robotparser模块,我们可以实现网站Robots协议的分析

      1、Robots协议

      也称为爬虫协议、机器人协议,它的全名叫做网络爬虫排除标准(Robots Exclusion Protocol),用来告诉爬虫和搜索引擎哪些网页可以抓取,哪些不可以抓取,它通常是一个robots.txt的文本文件,一般放在网站的根目录下。

      当搜索爬虫访问一个站点时,它首先会检查这个站点根目录下是否存在robots.txt文件,如果存在,搜索爬虫会根据其中定义的爬去范围来爬取,如果没有找到,搜索爬虫会访问所有可直接访问的页面

      我们来看下robots.txt的样例:

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

      它实现了对所有搜索爬虫只允许爬取public目录的功能,将上述内容保存为robots.txt文件放在网站根目录下,和网站的入口文件(index.html)放在一起

      1、User-agent描述了搜索爬虫的名称,将其设置为*则代表协议对任何爬虫有效,如设置为Baiduspider则代表规则对百度爬虫有效,如果有多条则对多个爬虫受到限制,但至少需要指定一条

      一些常见的搜索爬虫名称:

      • BaiduSpider 百度爬虫 www.baidu.com

      • Googlebot Google爬虫 www.google.com

      • 360Spider 360爬虫 www.so.com

      • YodaoBot 有道爬虫 www.youdao.com

      • ia_archiver Alexa爬虫 www.alexa.cn

      • Scooter altavista爬虫 www.altavista.com

      2、Disallow指定了不允许抓取的目录,如上例中设置的/则代表不允许抓取所有的页面

      3、Allow一般和Disallow一起使用,用来排除单独的某些限制,如上例中设置为/public/则表示所有页面不允许抓取,但可以抓取public目录

      设置示例:

      #禁止所有爬虫 User-agent: * Disallow: / #允许所有爬虫访问任何目录,另外把文件留空也可以 User-agent: * Disallow: #禁止所有爬虫访问某那些目录 User-agent: * Disallow: /home/ Disallow: /tmp/ #只允许某一个爬虫访问 User-agent: BaiduSpider Disallow: User-agent: * Disallow: /2、rebotparser模块

      用来解析robots.txt,该模块提供了一个类RobotFileParser,它可以根据某网站的robots.txt文件来判断一个抓取爬虫时都有权限来抓取这个网页

      urllib.robotparser.RobotFileParser(url='')

      robotparser类常用的方法:

      • set_url():用来设置robots.txt文件的连接,如果在创建RobotFileParser对象是传入了连接,就不需要在使用这个方法设置了

      • read():读取reobts.txt文件并进行分析,它不会返回任何内容,但执行那个了读取和分析操作

      • parse():用来解析robots.txt文件,传入的参数是robots.txt某些行的内容,并安装语法规则来分析内容

      • can_fetch():该方法传入两个参数,第一个是User-agent,第二个是要抓取的URL,返回的内容是该搜索引擎是否可以抓取这个url,结果为True或False

      • mtime():返回上次抓取和分析robots.txt的时间

      • modified():将当前时间设置为上次抓取和分析robots.txt的时间

      from urllib.robotparser import RobotFileParser rp = RobotFileParser() #创建对象 rp.set_url('www.cnblogs.com/robots.txt') #设置robots.txt连接,也可以在创建对象时指定 rp.read() #读取和解析文件 print(rp.can_fetch('*','i.cnblogs.com/EditPosts.aspx?postid=9170312&update=1')) #判断链接是否可以被抓取六、urllib3库

      urllib3增加了连接池等功能,两者互相都有补充的部分。许多Python的原生系统已经开始使用urllib3。

      urllib3提供了很多python标准库urllib里所没有的重要特性:

      • 线程安全

      • 连接池

      • 客户端SSL/TLS验证

      • 文件分部编码上传

      • 协助处理重复请求和HTTP重定位

      • 支持gzip和deflate压缩编码

      • 支持HTTP和SOCKS代理

      • 100%测试覆盖率

      urllib3是一个第三方库,pip安装:

      pip install urllib3

      通过urllib3访问一个网页,那么必须首先构造一个PoolManager对象,然后通过PoolMagent中的request方法或者 urlopen()方法来访问一个网页,两者几乎没有任何区别。

      class urllib3.poolmanager.PoolManager(num_pools = 10,headers = None,** connection_pool_kw )

      生成一个PoolManager所需要的参数:

      • num_pools 代表了缓存的池的个数,如果访问的个数大于num_pools,将按顺序丢弃最初始的缓存,将缓存的个数维持在池的大小。

      • headers 代表了请求头的信息,如果在初始化PoolManager的时候指定了headers,那么之后每次使用PoolManager来进行访问的时候,都将使用该headers来进行访问。

      • ** connection_pool_kw 是基于connection_pool 来生成的其它设置

      当访问网页完成之后,将会返回一个HTTPResponse对象。

      使用request()或者urlopen(),获取GET请求的响应内容:

      import urllib3 data = json.dumps({'abc': '123'}) www.baidu.com', body=data) resp2 = www.baidu.com', body=data) print(resp2.data.decode())

      使用request()或者urlopen(),进行 POST 请求:

      import urllib3 import json data = json.dumps({'abc': '123'}) www.www.50.233.137.33:80', headers={'connection': 'keep-alive'}) resp1 = proxy.request('POST', 'www.httpbin.org/post', fields=data) print(resp1.data.decode())

本文共计3738个文字,预计阅读时间需要15分钟。

如何使用urllib和urllib3构建长尾词查询的HTTP客户端?

一、urllib概述:urllib是Python中用于请求URL连接的官方标准库。当你安装了Python,这个库就已经可用,无需额外安装。它提供了基本的网络请求功能,涵盖了如GET、POST等基本的HTTP请求方法。在Python 2中,主要使用urllib和urllib2。

一、urllib概述:

urllib是Python中请求url连接的官方标准库,就是你安装了python,这个库就已经可以直接使用了,基本上涵盖了基础的网络请求功能。在Python2中主要为urllib和urllib2,在Python3中整合成了urllib。

Python3.x中将urllib2合并到了urllib,之后此包分成了以下四个模块:

  • urllib.request: 它是最基本的www.baidu.com" parsed = urllib.parse.urlparse(url) print(parsed) # 输出:ParseResult(scheme='www.baidu.com/index.html;user?a=6#comment2、urlsplit()、urlunsplit():URL分割与组合

    与urlparse()方法类似,它会返回5个部分,只是把params合并到path中。

    from urllib.parse import urlsplit result = urlsplit('www.baidu.com/index.html;user?id=5#comment') print(result) print(result.query) # output # SplitResult(scheme='www.baidu.com/index.html?a=5#comment3、urlencode()、parse_qs():查询字符串与字典类型转换

    urlencode() 将dict中的键值对以连接符&划分。

    urlencode()在构造GET请求参数时很有用,可以将字典类型的请求数据转变为url编码

    import urllib.parse dic = {'name':'melon','age':18} data = urllib.parse.urlencode(dic) print(data) #age=18&name=melon

    parse_qs()与urlencode()正好相反,它是用来反序列化的,如将GET参数转换回字典格式

    from urllib.parse import urlencode,parse_qs,urlsplit params = {'username':'zs','password':'123'} base_url='www.baidu.com' url=base_url+'?'+urlencode(params) #将字典转化为get参数 query=urlsplit(url).query #获去URL的query参数条件 print(parse_qs(query)) #根据获取的GET参数转换为字典格式 #output #{'username': ['zs'], 'password': ['123']}4、quote()、unquote():URL编码与解码

    quote:URL编码处理,该方法可以将内容转换为URL编码的格式。

    如参数中带有中文等非ASCII码时,有时会导致乱码的问题,此时用这个方法将中文字符转化为URL编码

    from urllib.parse import quote key='中文' url='www.baidu.com/s?key='+quote(key) print(url) #output #www.baidu.com/s?key=%E4%B8%AD%E6%96%87

    unquote(url):URL解码处理,与quote()相反,URL上的特殊字符还原

    from urllib.parse import quote, urlsplit, unquote key = '中文' url = 'www.baidu.com/s?key=' + quote(key) print(url) unq = urlsplit(url).query.split('=')[1] # 获取参数值 print(unquote(unq)) # 解码参数5、urljoin():将url的根域名和新url拼合成一个完整的url

    格式:urljoin(baseurl,newurl,allowFrag=None)

    通过将基本URL(base)与另一个URL(url)组合起来构建完整URL,它会使用基本URL组件,协议(schemm)、域名(netloc)、路径(path)、来提供给URL中缺失的部分进行补充,最后返回结果。

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

    通过urljoin()方法可以实现链接的解析、拼接和生成。

    import urllib.parse url = "www.baidu.com" new_path = urllib.parse.urljoin(url, "index.html") print(new_path) # 输出:<a href="www.baidu.com/index.html" rel="external nofollow" target="_blank">www.baidu.com/index.html</a>三、urllib.request模块1、urlretrieve():下载url到html文件。

    urlretrieve(url,filename,reporthook,data)

    不写路径filename则会被存为临时文件,可以用 urllib.urlcleanup() 来清理缓存

    file_name = urllib.request.urlretrieve('www.baidu.com','%s/baidu.html'%BASE_DIR)2、urlopen():打开一个url的方法,返回一个文件对象,然后可以进行类似文件对象的操作

    模块中最常用的函数为urlopen():

    urllib.request.urlopen(url, data=None, [timeout, ]*, cafile=None, capath=None, cadefault=False, context=None)

    参数如下:

    • url: 请求的网址,str类型,也可以是一个request对象

    • data:要发送到服务器的数据,data参数是可选的,内容为字节流编码格式的即bytes类型,如果传递data参数,urlopen将使用Post方式请求。

    • timeout:设置网站的访问超时时间,单位为秒,如果请求超出了设置时间还未得到响应则抛出异常,支持HTTP,HTTPS,FTP请求。

    • 其他参数:context参数,她必须是ssl.SSLContext类型,用来指定SSL设置,此外,cafile和capath这两个参数分别指定CA证书和它的路径,会在www.baidu.com') print(req.read().decode()) print(req.getheaders()) # 以列表元祖对的形式返回响应头信息 print(req.getheader('Content-Type')) # 返回响应头中的Content-Type值 print(req.info()) # 返回网页的头信息 print(req.info()['Content-Type']) # 返回响应头中的Content-Type值2、for循环读取

      不需要使用read()方法 。

      for line in urlopen('。。.html'): line = line.decode('utf-8') # Decoding the binary data to text. if 'EST' in line or 'EDT' in line: # look for Eastern Time print(line)3、GET请求

      GET请求和我们平常get访问方式一样,直接把参数写到网址上面就好了。

      import urllib.request import urllib.parse dic = {'name':'melon','age':18} data = urllib.parse.urlencode(dic) req = urllib.request.urlopen('127.0.0.1:8000/index?%s'%data) #通过urlopen方法访问拼接好的url content = req.read()4、POST请求

      urlopen()方法中,urlopen()默认的访问方式是GET,当在urlopen()方法中传入data参数时,则会发起POST请求。

      注意:传递的data数据需要为bytes格式,如data=b'word=hello'。

      import urllib.request import urllib.parse import json dic = {'name':'melon','age':18} data = urllib.parse.urlencode(dic) req = urllib.request.Request('127.0.0.1:8000/index', data.encode()) #encode:将url编码类型的请求数据转变为bytes类型 opener = urllib.request.urlopen(req) content = json.loads(opener.read().decode()) #read()方法是读取返回bytes数据内容,decode转换后为str5、请求头参数模拟

      当我们需要模拟一些其他的参数的时候,简单的urlopen() 方法已经无法满足我们的需求了,这个时候我们就需要使用下面的urllib.request中的Request对象来帮助我们实现一些其它参数的模拟,比如请求头。

      Request对象如下所示:

      如何使用urllib和urllib3构建长尾词查询的HTTP客户端?

      # Request对象实例化 req = urllib.request.Request(url, data=None, headers={},origin_req_host=None,unverifiable=False, method=None)

      • url:请求的URL,必须传递的参数,其他都是可选参数

      • data:上传的数据,必须传bytes字节流类型的数据,如果它是字典,可以先用urllib.parse模块里的urlencode()编码

      • headers:它是一个字典,传递的是请求头数据,可以通过它构造请求头,也可以通过调用请求实例的方法add_header()来添加
        例如:修改User_Agent头的值来伪装浏览器,比如火狐浏览器可以这样设置:
        {'User-Agent':'Mozilla/5.0 (compatible; MSIE 5.5; Windows NT)'}

      • origin_req_host:指请求方的host名称或者IP地址

      • unverifiable:表示这个请求是否是无法验证的,默认为False,如我们请求一张图片如果没有权限获取图片那它的值就是true

      • method:是一个字符串,用来指示请求使用的方法,如:GET,POST,PUT等

      from urllib import request url='localhost' p=HTTPPasswordMgrWithDefaultRealm() #构造密码管理实例 p.add_password(None,url,username,passowrd) #添加用户名和密码到实例中 auth_handler=HTTPBasicAuthHandler(p) #传递密码管理实例构建一个验证实例 opener=build_opener(auth_handler) #构建一个Opener try: result=opener.open(url) #打开链接,完成验证,返回的结果是验证后的页面内容 html=result.read().decode('utf-8') print(html) except URLError as e: print(e.reason)2、设置Proxy代理:ProxyHandler

      使用爬虫来爬取数据的时候,如果过于频繁的访问,而且网站还设有限制的话,很有可能会禁封我们的ip地址,这个时候就需要设置代理,来隐藏我们的真实IP。

      urllib提供了urllib.request.ProxyHandler()方法可动态的设置代理IP池。将代理IP以字典形式传入该方法,然后通过urllib.reques.build_opener()创建opener对象,用该对象的open()方法向服务器发送请求。

      from urllib import request url = 'www.baidu.com') # 使用这个opener来发起请求 # 查看之前的cookie对象,则可以看到访问百度获得的cookie for i in cookie: print(i)

      cookies保存到文件:

      1、以Mozilla型浏览器的cookies格式:

      cookie=www.baidu.com') #请求 cookie.save(ignore_discard=True,ignore_expires=True)

      从文件中读取cookies:

      2、也可以保存为libwww-perl(LWP)格式的Cookies文件

      cookie=www.baidu.com') #请求 print(response.read().decode('utf-8'))

      当然,如果把上面这个生成的opener对象使用install_opener方法来设置为全局的,opener对象之后的每次访问都会带上这个cookie。

      4、证书验证

      通过添加忽略ssl证书验证关闭证书验证,由于urllib并没有很好的处理ssl的对象,所以在这里我们需要用到一个别的库,即ssl库,如下:

      import ssl from urllib import request context = ssl._create_unverified_context() res = urllib.request.urlopen(request, context=context)

      当你 urllib.urlopen一个 hehe,com/index') except error.URLError as e: print(e.reason) #如果网页不存在不会抛出异常,而是返回捕获的异常错误的原因(Not Found)

      reason如超时则返回一个对象

      import socket import urllib.request import urllib.error try: response=urllib.request.urlopen('www.baidu.com',timeout=0.001) except urllib.error.URLError as e: print(e.reason) if isinstance(e.reason,socket.timeout): print('time out')2、HTTPError

      它是URLError的子类,专门用来处理HTTP请求错误,比如认证请求失败,它有3个属性:

      • code:返回HTTP的状态码,如404页面不存在,500服务器错误等

      • reason:同父类,返回错误的原因

      • headers:返回请求头

      举例:

      from urllib import request,error try: response=request.urlopen('cuiqingcai.com/index.htm') except error.HTTPError as e: #先捕获子类异常 print(e.reason,e.code,e.headers,sep='\n') except error.URLError as e: #再捕获父类异常 print(e.reason) else: print('request successfully')五、urllib.robotparser模块

      利用urllib的robotparser模块,我们可以实现网站Robots协议的分析

      1、Robots协议

      也称为爬虫协议、机器人协议,它的全名叫做网络爬虫排除标准(Robots Exclusion Protocol),用来告诉爬虫和搜索引擎哪些网页可以抓取,哪些不可以抓取,它通常是一个robots.txt的文本文件,一般放在网站的根目录下。

      当搜索爬虫访问一个站点时,它首先会检查这个站点根目录下是否存在robots.txt文件,如果存在,搜索爬虫会根据其中定义的爬去范围来爬取,如果没有找到,搜索爬虫会访问所有可直接访问的页面

      我们来看下robots.txt的样例:

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

      它实现了对所有搜索爬虫只允许爬取public目录的功能,将上述内容保存为robots.txt文件放在网站根目录下,和网站的入口文件(index.html)放在一起

      1、User-agent描述了搜索爬虫的名称,将其设置为*则代表协议对任何爬虫有效,如设置为Baiduspider则代表规则对百度爬虫有效,如果有多条则对多个爬虫受到限制,但至少需要指定一条

      一些常见的搜索爬虫名称:

      • BaiduSpider 百度爬虫 www.baidu.com

      • Googlebot Google爬虫 www.google.com

      • 360Spider 360爬虫 www.so.com

      • YodaoBot 有道爬虫 www.youdao.com

      • ia_archiver Alexa爬虫 www.alexa.cn

      • Scooter altavista爬虫 www.altavista.com

      2、Disallow指定了不允许抓取的目录,如上例中设置的/则代表不允许抓取所有的页面

      3、Allow一般和Disallow一起使用,用来排除单独的某些限制,如上例中设置为/public/则表示所有页面不允许抓取,但可以抓取public目录

      设置示例:

      #禁止所有爬虫 User-agent: * Disallow: / #允许所有爬虫访问任何目录,另外把文件留空也可以 User-agent: * Disallow: #禁止所有爬虫访问某那些目录 User-agent: * Disallow: /home/ Disallow: /tmp/ #只允许某一个爬虫访问 User-agent: BaiduSpider Disallow: User-agent: * Disallow: /2、rebotparser模块

      用来解析robots.txt,该模块提供了一个类RobotFileParser,它可以根据某网站的robots.txt文件来判断一个抓取爬虫时都有权限来抓取这个网页

      urllib.robotparser.RobotFileParser(url='')

      robotparser类常用的方法:

      • set_url():用来设置robots.txt文件的连接,如果在创建RobotFileParser对象是传入了连接,就不需要在使用这个方法设置了

      • read():读取reobts.txt文件并进行分析,它不会返回任何内容,但执行那个了读取和分析操作

      • parse():用来解析robots.txt文件,传入的参数是robots.txt某些行的内容,并安装语法规则来分析内容

      • can_fetch():该方法传入两个参数,第一个是User-agent,第二个是要抓取的URL,返回的内容是该搜索引擎是否可以抓取这个url,结果为True或False

      • mtime():返回上次抓取和分析robots.txt的时间

      • modified():将当前时间设置为上次抓取和分析robots.txt的时间

      from urllib.robotparser import RobotFileParser rp = RobotFileParser() #创建对象 rp.set_url('www.cnblogs.com/robots.txt') #设置robots.txt连接,也可以在创建对象时指定 rp.read() #读取和解析文件 print(rp.can_fetch('*','i.cnblogs.com/EditPosts.aspx?postid=9170312&update=1')) #判断链接是否可以被抓取六、urllib3库

      urllib3增加了连接池等功能,两者互相都有补充的部分。许多Python的原生系统已经开始使用urllib3。

      urllib3提供了很多python标准库urllib里所没有的重要特性:

      • 线程安全

      • 连接池

      • 客户端SSL/TLS验证

      • 文件分部编码上传

      • 协助处理重复请求和HTTP重定位

      • 支持gzip和deflate压缩编码

      • 支持HTTP和SOCKS代理

      • 100%测试覆盖率

      urllib3是一个第三方库,pip安装:

      pip install urllib3

      通过urllib3访问一个网页,那么必须首先构造一个PoolManager对象,然后通过PoolMagent中的request方法或者 urlopen()方法来访问一个网页,两者几乎没有任何区别。

      class urllib3.poolmanager.PoolManager(num_pools = 10,headers = None,** connection_pool_kw )

      生成一个PoolManager所需要的参数:

      • num_pools 代表了缓存的池的个数,如果访问的个数大于num_pools,将按顺序丢弃最初始的缓存,将缓存的个数维持在池的大小。

      • headers 代表了请求头的信息,如果在初始化PoolManager的时候指定了headers,那么之后每次使用PoolManager来进行访问的时候,都将使用该headers来进行访问。

      • ** connection_pool_kw 是基于connection_pool 来生成的其它设置

      当访问网页完成之后,将会返回一个HTTPResponse对象。

      使用request()或者urlopen(),获取GET请求的响应内容:

      import urllib3 data = json.dumps({'abc': '123'}) www.baidu.com', body=data) resp2 = www.baidu.com', body=data) print(resp2.data.decode())

      使用request()或者urlopen(),进行 POST 请求:

      import urllib3 import json data = json.dumps({'abc': '123'}) www.www.50.233.137.33:80', headers={'connection': 'keep-alive'}) resp1 = proxy.request('POST', 'www.httpbin.org/post', fields=data) print(resp1.data.decode())