Python 标准库 —— urllib(下载进度)

注意:python 3 环境下的 urllib 库,将 urlopen、urlretrieve、quote 等实用函数统一封装在 urllib.request 下。

在可使用的各种网络函数库中,功能最为强大的可能是 urllib 和 urllib2 了。通过它们在网络上访问文件,就好像访问本地文件一样。通过一个简单的函数调用(urlopen),几乎可以把任何 url 所指向的东西作为程序的输入。想象一下,如果将这两个模块和 re 模块结合使用的效果:可以下载 web 页面,提取信息,以及自动生成报告等。

  • urlencode:将字典型的请求参数配置,编码为url能够识别的形式;

    >> request_paras = {
            'reportTime': '2017-12-31',
            'pageNum': 1
        }
    >> urlencode(paras)
    'reportTime=2017-12-31&pageNum=1'
    >> url = 'http://s.askci.com/stock/a/?' + urlencode(request_paras)
    >> url
    'http://s.askci.com/stock/a/?reportTime=2017-12-31&pageNum=1'
    >> 
    

0. url 中的中文:quote、unquote

  • 来看百度上野树里吧的首页 url:http://tieba.baidu.com/f?kw=��Ұ����&fr=ala0&loc=rec&traceid=,kw所对的(��Ұ����)无疑就是上野树里转码后的字符串表示,我们尝试将其解码成中文姓氏:

    >> from urllib.parse import quote, unquote
    >> s = '%C9%CF%D2%B0%CA%F7%C0%EF'
    >> unquote(s)
     '��Ұ����'
    		 # 却是无法显示的乱码,这是因为 urllib 默认的编码解码都是 utf-8,而百度采用的编码为 gbk
    >> unquote(s, encoding='gbk')
    '上野树里'
    
  • 下面我们来构造,新垣结衣的百度贴吧首页 url:

    >> s = '新垣结衣'
    >> decode_s = quote(s, encoding='gbk')
    >> decode_s
    '%D0%C2%D4%AB%BD%E1%D2%C2'
    >> construct_url = 'http://tieba.baidu.com/f?kw=' + decode_s + '&fr=ala0&loc=rec&traceid='
    http://tieba.baidu.com/f?kw=%D0%C2%D4%AB%BD%E1%D2%C2&fr=ala0&loc=rec&traceid=
    

1. urllib.urlopen():打开远程文件

>>> from urllib import urlopen
>>> webpage = urlopen('http://www.python.org')

可以像打开本地文件一样打开远程文件,不同之处在于只能使用只读模式,使用来自 urllib 的 urlopen 而不是 file 或者 open。

urlopen 返回的类文件对象(instance)支持 close/read/readline/readlines方法。

2. urllib.urlretrieve():获取远程文件

>>> from urllib import urlretrieve
>>> urlretrieve('http://www.python.org', '/root/workspaces/python_webpage.html')

urlopen 返回一个能从中读取数据的类文件对象(instance)。如果希望 urllib 为你下载文件并在本地文件中存储一个文件的副本,则可以使用 urlretrive。

从 url 上加载数据到本地:

if (not os.path.isfile(dataset)) and dataset == 'mnist.pkl.gz':
	origin = 'http://www.iro.umontreal.ca/~lisa/deep/data/mnist/mnist.pkl.gz'
	print 'Downloading data from %s' % origin
	urllib.urlretrieve(origin, dataset)

3. 下载进度

  • 如下的函数作为 urlretrieve 的 reporthook 命名参数的回调函数,

    def download_report(count, block_size, total_size):
        downloaded = count * block_size
        percent = 100. * downloaded / total_size
        percent = min(100, percent)
        print('downloaded %d, %.2f%% completed' % (downloaded, percent))
    
  • 查看 urlretrieve 源码发现,total_size 根据 Content-length 获取,如果未获得该参数,则 total_size 默认传参为 -1:

    ![这里写图片描述](https://img-blog.csdn.net/20180624141228819?watermark/2/text/aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2xhbmNodW5odWk=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70)

4. quote/quote_plus

除了通过 URL 读取和下载文件,urllib 还提供了一些函数操作 URL 本身,

  • quote(string[, safe])。返回一个字符串,其中所有的特殊字符(这些字符在 URL 中有特殊含义)都已被对 URL 友好的字符所代替。safe 字符串包含了不应该采用这种方式编码的字符,默认的是/
    • parse.quote('~')%7E
    • parse.quote(':')%3A
  • quote_plus(string[, safe]),功能和 quote 差不多,但用+号代替空格
  • unquote(string),和 quote 相反
  • unquote_plus(string),和 quote_plus相反

##4. parse_qs/parse_qsl

>> from urllib.parse import parse_qs
>> my_values = parse_qs('red=5&blue=0&green=', keep_blank_values=True)
>> print(repr(my_values))
{‘red’: [‘5’], ‘green’: [”], ‘blue’: [‘0’]}

如果 url 的 query 中有同一个 key 对应多个 value,其中 parse_qs() 可以把该相同 key 的 value 放在一个 list 中。

你可能感兴趣的:(爬虫)