zoukankan      html  css  js  c++  java
  • URLLib库使用

    Date: 2019-06-19

    Author: Sun

    urllib

    ​ 在Python 3以后的版本中,urllib2这个模块已经不单独存在(也就是说当你import urllib2时,系统提示你没这个模块),urllib2被合并到了urllib中,叫做urllib.request 和 urllib.error

    urllib整个模块分为urllib.request, urllib.parse, urllib.error。

    urllib是一个包含几个模块来处理请求的库。

    分别是:

    • urllib.request 发送http请求
    • urllib.error 处理请求过程中,出现的异常。
    • urllib.parse 解析url
    • urllib.robotparser 解析robots.txt 文件

    网页抓取

    ​ 所谓网页抓取,就是把URL地址中指定的网络资源从网络流中读取出来,保存到本地。 在Python中有很多库可以用来抓取网页,我们先学习urllib.request库。

    1. urlopen

    定义:

    urlopen(url, data=None, timeout=socket._GLOBAL_DEFAULT_TIMEOUT,
    *, cafile=None, capath=None, cadefault=False, context=None)
    

    功能:

    像读文件一样读网页

    案例1:

    采用urllib抓取百度网页

    # -*- coding: utf-8 -*-
    __author__ = 'sun'
    __date__ = '2019/6/19 9:54'
    
    #import urllib.request
    from urllib import request
    
    # 向指定的url地址发送请求,并返回服务器响应的类文件对象
    response = request.urlopen("http://www.baidu.com/")
    
    # 服务器返回的类文件对象支持Python文件对象的操作方法
    # read()方法就是读取文件里的全部内容,返回字符串
    html = response.read().decode('utf-8')   # bytes  ---》 str   decode
                                             # str    --> bytes   encode
    
    # 打印响应内容
    print(html)
    

    2. urlretrieve

    `>>> ``help``(urllib.urlretrieve)`
    
    urlretrieve(url, filename=None, reporthook=None, data=None) 
    
    - 参数 finename 指定了保存本地路径(如果参数未指定,urllib会生成一个临时文件保存数据。)
    - 参数 reporthook 是一个回调函数,当连接上服务器、以及相应的数据块传输完毕时会触发该回调,我们可以利用这个回调函数来显示当前的下载进度。
    - 参数 data 指 post 到服务器的数据,该方法返回一个包含两个元素的(filename, headers)元组,filename 表示保存到本地的路径,header 表示服务器的响应头。
    

    功能:下载网页到文件

    url = 'http://www.python.org/ftp/python/2.7.5/Python-2.7.5.tar.bz2'
    urllib.urlretrieve(url,local)
    

    下载百度网站,保存到本地文件

    from urllib import request
    
    baidu = request.urlretrieve('http://www.baidu.com','F:\\TX课堂\\授课内容\\第二部分-网络爬虫\\课件\\day02\\doc\\badu.html')
    
    #如果urlretrieve不传文件名的话会自动生成,运行完程序可以删除
    request.urlcleanup()
    #urlcleanup 
    #清除urlretrieve产生的临时文件,及opener对象 
    

    扩展:

    加入下载进度

    from urllib import  request
    import os
    def Schedule(a,b,c):
        '''''
        a:已经下载的数据块
        b:数据块的大小
        c:远程文件的大小
        '''
        per = 100.0 * a * b / c
        if per > 100 :
            per = 100
        print('%.2f%%' % per)
    
    url = 'http://www.python.org/ftp/python/2.7.5/Python-2.7.5.tar.bz2'
    #local = url.split('/')[-1]
    #local = os.path.join('/data/software','Python-2.7.5.tar.bz2')
    local = os.path.join('F:\\TX课堂\\授课内容\\第二部分-网络爬虫\\课件\\day02\\doc','Python-2.7.5.tar.bz2')
    request.urlretrieve(url,local,Schedule)
    

    3. Request对象

    class Request:
        def __init__(self, url, data=None, headers={},  origin_req_host=None, unverifiable=False, method=None)
    # url是网址,data数据,header头消息,origin_req_host相当于referrer,method请求的方法(如get,post)
    

    需要添加headers头信息,urlopen不支持,需要使用Request

    案例:访问简书网站信息

    # -*- coding: utf-8 -*-
    __author__ = 'sun'
    __date__ = '2019/6/19 9:54'
    
    from urllib import  request
    from urllib.request import Request
    
    url = 'https://www.jianshu.com'
    # 增加header
    headers = {
    'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.96 Safari/537.36',
    }
    req = Request(url,headers=headers)    #多一层封装
    # or   req.add_header("Connection", "keep-alive")
    response = request.urlopen(req)
    html = response.read().decode('utf-8')    # read()方法就是读取文件里的全部内容,返回字符串
    #在urllib里面 判断是get请求还是post请求,就是判断是否提交了data参数
    print(f'method:{req.get_method()}')
    code = response.getcode()   #返回码
    resp_url = response.geturl()
    resp_head_info = response.info()
    print("#####################")
    print(f"response code:{code}, url:{resp_url}")
    print(f"head_info:{resp_head_info}")
    
    

    4. urllib.error

    urllib.error可以接收有urllib.request产生的异常。urllib.error中常用的有两个方法,URLError和HTTPError。URLError是OSError的一个子类,

    HTTPError是URLError的一个子类,服务器上HTTP的响应会返回一个状态码,根据这个HTTP状态码,我们可以知道我们的访问是否成功。

    URLError

    URLError产生原因一般是: 网络无法连接、服务器不存在等。

    例如访问一个不存在的url

    import urllib.error
    from urllib  import  request
    requset = urllib.request.Request('http://www.usahfkjashfj.com/')   #无效url
    try:
        urllib.request.urlopen(requset).read()
    except urllib.error.URLError as e:
        print(e.reason)
    else:
        print('success')
    
    

    5. 设置代理

    (1)UA代理

    USER_AGENTS = [
        "Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Win64; x64; Trident/5.0; .NET CLR 3.5.30729; .NET CLR 3.0.30729; .NET CLR 2.0.50727; Media Center PC 6.0)",
        "Mozilla/5.0 (compatible; MSIE 8.0; Windows NT 6.0; Trident/4.0; WOW64; Trident/4.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; .NET CLR 1.0.3705; .NET CLR 1.1.4322)",
        "Mozilla/4.0 (compatible; MSIE 7.0b; Windows NT 5.2; .NET CLR 1.1.4322; .NET CLR 2.0.50727; InfoPath.2; .NET CLR 3.0.04506.30)",
        "Mozilla/5.0 (Windows; U; Windows NT 5.1; zh-CN) AppleWebKit/523.15 (KHTML, like Gecko, Safari/419.3) Arora/0.3 (Change: 287 c9dfb30)",
        "Mozilla/5.0 (X11; U; Linux; en-US) AppleWebKit/527+ (KHTML, like Gecko, Safari/419.3) Arora/0.6",
        "Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8.1.2pre) Gecko/20070215 K-Ninja/2.1.1",
        "Mozilla/5.0 (Windows; U; Windows NT 5.1; zh-CN; rv:1.9) Gecko/20080705 Firefox/3.0 Kapiko/3.0",
        "Mozilla/5.0 (X11; Linux i686; U;) Gecko/20070322 Kazehakase/0.4.5"
    ]
    user_agent = random.choice(USER_AGENTS)
    
    headers = {
        'User-Agent': user_agent
    }
    
    

    (2)IP代理

    当需要抓取的网站设置了访问限制,这时就需要用到代理来抓取数据。

    # -*- coding: utf-8 -*-
    __author__ = 'sun'
    __date__ = '2019/6/19 9:54'
    
    from urllib import  request
    from urllib.request import Request
    
    from urllib.error import URLError
    
    from urllib.request import ProxyHandler, build_opener
    
    url = 'http://httpbin.org/get'
    #url = 'http://www.baidu.com'
    
    proxy = '39.134.108.89:8080'
    # 参数是字典,键名是协议类型,健值是代理
    proxy_handler = ProxyHandler({
        'http': 'http://' + proxy,
        'https': 'https://' + proxy
    })
    # Opener已经设置好代理了
    opener = build_opener(proxy_handler)
    try:
        response = opener.open(url)
        # 运行结果是一个JSON
        print(response.read().decode('utf-8'))
    except URLError as e:
        print(e.reason)
    
    

    client --------> server

    IP proxy

    client ----> proxy ----> server

  • 相关阅读:
    【网络文摘】Androidguy:当你的才华还无法撑起你的野心时,那么应该静下心来学习
    【Android 百度地图实战】2.几种地图图层的显示
    【Android 百度地图实战】1.构建一个基础的地图页面
    【Window OS】”对于目标文件系统,文件XXXXX过大“导致无法进行文件操作的解决方法
    【ASP.NET 问题】IIS发布网站后出现 "处理程序“PageHandlerFactory-Integrated”在其模块列表中有一个错误"的解决办法
    【Javascript Demo】谷歌地图简单实现(附遮罩层和弹出层实现)
    【Javascript Demo】遮罩层和百度地图弹出层简单实现
    【Javascript Demo】遮罩层和弹出层简单实现
    【网络文摘】程序人生:我们工作到底为了什么
    Android手势密码--设置和校验
  • 原文地址:https://www.cnblogs.com/sunBinary/p/11055647.html
Copyright © 2011-2022 走看看