Study「Python」:文件下載

有時候從網絡下載包括圖片這樣的文件是很常見的,這裏介紹三種文件下載的方法。

目錄

一、urlretrieve函數

(一)urlretrieve函數簡介

(二)下載進度

(三)實例

二、urlopen函數

(一)urlopen函數介紹

(二)實例

三、get函數

(一)get函數介紹

(二)實例


一、urlretrieve函數

(一)urlretrieve函數簡介

urllib.request.urlretrieve(url, filename=None, reporthook=None, data=None)

def urlretrieve(url, filename=None, reporthook=None, data=None):
    """
    Retrieve a URL into a temporary location on disk.
    將URL檢索到磁盤上的臨時位置。

    Requires a URL argument. If a filename is passed, it is used as
    the temporary file location. The reporthook argument should be
    a callable that accepts a block number, a read size, and the
    total file size of the URL target. The data argument should be
    valid URL encoded data.
    需要URL參數。如果傳遞了filename,則將其用作臨時文件位置。reporthook參數應該是一個回調的函數,它接受URL目標的數據塊編號、讀取大小和總文件大小。data參數應該是有效的URL編碼的數據。

    If a filename is passed and the URL points to a local resource,
    the result is a copy from local file to new file.
    如果傳遞了一個文件名,並且URL指向本地資源,則結果是從本地文件複製到新文件。

    Returns a tuple containing the path to the newly created
    data file as well as the resulting HTTPMessage object.
    返回一個元組,其中包含到新創建的數據文件的路徑以及結果HTTPMessage對象。
    """

總結一下就是:

  •  url:資源地址,可以指向本地資源(當指向本地資源時,該過程相當於複製文件到新的位置
  • filename:本地路徑(如果參數未指定,urllib.request 會生成一個臨時文件來保存數據
  • reporthook:是一個回調函數,該回調函數接受三個參數:數據塊編號讀取大小總文件大小該函數可以用來顯示當前的下載進度
  • data:有效的URL編碼的數據

(二)下載進度

上面說了,我們可以用 reporthook 來調用一個顯示下載進度的程序,這裏我們再回顧一下三個參數(分別用abc表示)的含義:

  • 數據塊編號(a):數據塊編號順序爲 \left \{ 0,1,2,...,n \right \} ,假設當前數據塊編號爲 2 ,顯然,已經下載完成的數據塊數量也爲 2 ,所以我們可以簡單地認爲 a 就是已經下載完成的數據塊數量
  • 讀取大小(b):每次下載的數據塊大小
  • 總文件大小(c):文件的總大小

一個簡單的計算公式即可得到當前完成的下載量佔全部文件的比例:

per = \frac{a\times b}{c}

常用百分比來表示進度,具體代碼如下:

def schedule(a, b, c):
    # a:已經下載的數據塊數量
    # b:每次下載的數據塊大小
    # c:文件的總大小
    per = 100.0 * a * b / c
    if per > 100:
        per = 100
    print('%.2f%%' % per)

(三)實例

以下載百度首頁 .html 文件爲例:

from urllib.request import urlretrieve


def schedule(a, b, c):
    # a:已經下載的數據塊數量
    # b:每次下載的數據塊大小
    # c:文件的總大小
    per = 100.0 * a * b / c
    if per > 100:
        per = 100
    print('%.2f%%' % per)


if __name__ == '__main__':

    url = 'http://www.baidu.com'
    filepath = './baidu.html'
    urlretrieve(url, filepath, schedule)

二、urlopen函數

(一)urlopen函數介紹

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

def urlopen(url, data=None, timeout=socket._GLOBAL_DEFAULT_TIMEOUT,
            *, cafile=None, capath=None, cadefault=False, context=None):
    '''Open the URL url, which can be either a string or a Request object.
    打開URL URL,它可以是一個字符串,也可以是一個請求對象。

    *data* must be an object specifying additional data to be sent to
    the server, or None if no such data is needed.  See Request for
    details.
    *data*必須是一個指定要發送到服務器的額外數據的對象,如果不需要這樣的數據,則爲None。詳情請見請求。

    urllib.request module uses HTTP/1.1 and includes a "Connection:close"
    header in its HTTP requests.
    urllib.request模塊使用HTTP/1.1,並在其HTTP請求中包含一個“Connection:close”報頭。

    The optional *timeout* parameter specifies a timeout in seconds for
    blocking operations like the connection attempt (if not specified, the
    global default timeout setting will be used). This only works for HTTP,
    HTTPS and FTP connections.
    可選的*timeout*參數爲阻塞操作(如連接嘗試)指定超時(以秒爲單位)(如果未指定,將使用全局缺省超時設置)。這隻適用於HTTP、HTTPS和FTP連接。

    If *context* is specified, it must be a ssl.SSLContext instance describing
    the various SSL options. See HTTPSConnection for more details.
    如果指定了*context*,那麼它必須是一個ssl。描述各種SSL選項的SSLContext實例。參見HTTPSConnection瞭解更多細節。

    The optional *cafile* and *capath* parameters specify a set of trusted CA
    certificates for HTTPS requests. cafile should point to a single file
    containing a bundle of CA certificates, whereas capath should point to a
    directory of hashed certificate files. More information can be found in
    ssl.SSLContext.load_verify_locations().
    可選的*cafile*和*capath*參數爲HTTPS請求指定一組受信任的CA證書。cafile應該指向一個包含一組CA證書的文件,而capath應該指向一個散列證書文件目錄。更多信息可以在ssl.SSLContext.load_verify_locations()中找到。

    The *cadefault* parameter is ignored.
    忽略*cadefault*參數。

    This function always returns an object which can work as a context
    manager and has methods such as
    該函數總是返回一個對象,該對象可以作爲上下文管理器使用,並且具有以下方法

    * geturl() - return the URL of the resource retrieved, commonly used to
      determine if a redirect was followed
      geturl() - 返回所檢索資源的URL,通常用於確定是否遵循了重定向

    * info() - return the meta-information of the page, such as headers, in the
      form of an email.message_from_string() instance (see Quick Reference to
      HTTP Headers)
      info() - 以email.message_from_string()實例的形式返回頁面的元信息,如標題(參見HTTP標題的快速引用)

    * getcode() - return the HTTP status code of the response.  Raises URLError
      on errors.
      getcode() - 返回響應的HTTP狀態碼。在錯誤上引發URLError。

    For HTTP and HTTPS URLs, this function returns a http.client.HTTPResponse
    object slightly modified. In addition to the three new methods above, the
    msg attribute contains the same information as the reason attribute ---
    the reason phrase returned by the server --- instead of the response
    headers as it is specified in the documentation for HTTPResponse.
    對於HTTP和HTTPS url,此函數返回HTTP.client。HTTPResponse對象略有修改。除了上述三個新方法之外,msg屬性還包含與reason屬性相同的信息——服務器返回的原因短語——而不是響應標頭,因爲它在HTTPResponse文檔中指定了響應標頭。

    For FTP, file, and data URLs and requests explicitly handled by legacy
    URLopener and FancyURLopener classes, this function returns a
    urllib.response.addinfourl object.
    對於由遺留URLopener和FancyURLopener類顯式處理的FTP、file和data url和請求,此函數將返回一個urllib.response。addinfourl對象。

    Note that None may be returned if no handler handles the request (though
    the default installed global OpenerDirector uses UnknownHandler to ensure
    this never happens).
    注意,如果沒有處理程序處理請求,可能不會返回任何值(儘管默認安裝的全局OpenerDirector使用UnknownHandler來確保不會發生這種情況)。

    In addition, if proxy settings are detected (for example, when a *_proxy
    environment variable like http_proxy is set), ProxyHandler is default
    installed and makes sure the requests are handled through the proxy.
    此外,如果檢測到代理設置(例如,設置了*_proxy環境變量,如http_proxy),則ProxyHandler是默認安裝的,並確保通過代理處理請求。

    '''

(二)實例

from urllib.request import urlopen


def download(url):

    f = urlopen(url)
    html = f.read()
    with open("./baidu.html", "wb") as fb:
        fb.write(html)


if __name__ == '__main__':
    my_url = 'http://www.baidu.com'

    download(my_url)

三、get函數

(一)get函數介紹

requests.get(url, params=None, **kwargs)

def get(url, params=None, **kwargs):
    r"""Sends a GET request.
    發送一個GET請求。

    :param url: URL for the new :class:`Request` object.
     param url: 新:class: 'Request'對象的URL。
    :param params: (optional) Dictionary, list of tuples or bytes to send
        in the query string for the :class:`Request`.
     param params: (可選)字典,元組或字節的列表發送在查詢字符串:class: 'Request'。
    :param \*\*kwargs: Optional arguments that ``request`` takes.
     param \*\*kwargs: ‘request’接受的可選參數。
    :return: :class:`Response <Response>` object
     return: :class:`Response <Response>`對象
    :rtype: requests.Response
     rtype: requests.Response
    """

(二)實例

import requests


def download(url):

    r = requests.get(url)
    with open("./baidu.html", "w") as f:
        f.write(r.text)


if __name__ == '__main__':
    my_url = 'http://www.baidu.com'

    download(my_url)

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章