使用 Python 从 URL 下载文件的 5 种方法

使用Python从URL下载文件的多种方法

在处理Python项目时,你可能需要从网络上的特定URL下载文件。虽然可以手动下载,但使用Python脚本以编程方式下载会更便捷。本文将探讨几种使用Python从网络下载文件的不同方法,包括使用内置模块和第三方库。

如何使用Python从URL下载文件

如果你熟悉Python,你可能见过这个著名的XKCD Python漫画:

漫画来源:西科CD

为了演示,我们将尝试使用各种方法将这张XKCD漫画的PNG图片下载到本地工作目录。

在接下来的内容中,我们将使用多个第三方Python库。建议在项目的专用虚拟环境中安装它们。

使用urllib.request模块

Python的内置urllib.request模块提供了从URL下载文件的功能。这个模块可以发送HTTP请求并处理URL,它提供了一种与网络资源交互的简单方式,包括从网站获取数据。

现在让我们使用urllib.request从其URL下载XKCD Python漫画:

import urllib.request

url="https://imgs.xkcd.com/comics/python.png"
urllib.request.urlretrieve(url, 'xkcd_comic.png')

以上代码执行了以下步骤:

  • 导入urllib.request模块。
  • 设置XKCD Python漫画图片的URL。
  • 使用urllib.request.urlretrieve下载图片,并将其保存为当前目录中的”xkcd_comic.png”。

现在,如果你在终端运行ls命令查看当前目录的内容,你将看到”xkcd_comic.png”文件:

使用requests库

requests库是一个非常流行且广泛使用的Python库,用于发送HTTP请求和检索内容。 你需要先安装它:

pip install requests

如果在同一目录下创建了新的Python脚本,请在运行当前脚本之前删除之前下载的”xkcd_comic.png”。

import requests

url="https://imgs.xkcd.com/comics/python.png"
response = requests.get(url)

with open('xkcd_comic.png', 'wb') as file:
    file.write(response.content)

这段代码的执行步骤如下:

  • 导入requests库。
  • 设定XKCD Python漫画图片的URL。
  • 使用requests.get向URL发送GET请求。
  • 将响应内容(图像数据)以二进制写入模式保存为”xkcd_comic.png”。

打印目录内容时,你会看到下载的图片:

使用urllib3

我们已经了解了如何使用内置的urllib.request,但你也可以使用第三方库urllib3

urllib3是一个用于发送HTTP请求和管理连接的Python库,它比内置的urllib模块更可靠和高效。它提供了连接池、请求重试和线程安全等功能,使其成为在Python应用程序中处理HTTP通信的可靠选择。

使用pip安装urllib3:

pip install urllib3

现在让我们使用urllib3库下载XKCD Python漫画:

import urllib3

url="https://imgs.xkcd.com/comics/python.png"

http = urllib3.PoolManager()

response = http.request('GET', url)

image_data = response.data

file_name="xkcd_comic.png"

with open(file_name, 'wb') as file:
    file.write(image_data)

这种方法看起来比之前使用urllib.requestsrequests库的方法更复杂一些。让我们分解一下步骤:

  • 我们首先导入urllib3模块,它提供了发送HTTP请求的功能。
  • 然后我们指定XKCD漫画图像的URL。
  • 接下来,我们创建urllib3.PoolManager()的实例。这个对象管理连接池,并允许我们发送HTTP请求。
  • 然后,我们使用http.request('GET', url)方法向指定的URL发送HTTP GET请求。这个请求获取XKCD漫画的内容。
  • 请求成功后,我们使用response.data从HTTP响应中检索内容(图像数据)。
  • 最后,我们将图像数据(从响应中检索)写入文件。

运行Python脚本后,你将得到如下输出:

使用wget

wget Python库简化了从URL下载文件的过程,你可以使用它来检索网络资源,尤其适用于自动化下载任务。

你可以使用pip安装wget库,然后使用它的功能从URL下载文件:

pip install wget

以下代码片段使用wget模块下载XKCD Python漫画并将其保存为工作目录中的”xkcd_comic.png”:

import wget

url="https://imgs.xkcd.com/comics/python.png"
wget.download(url, 'xkcd_comic.png')

代码执行了以下操作:

  • 导入wget模块。
  • 设置XKCD Python漫画图片的URL。
  • 使用wget.download下载图像,并将其保存为当前目录中的”xkcd_comic.png”。

当你使用wget下载XKCD漫画时,你将看到类似以下输出:

使用PyCURL

如果你使用过Linux或Mac电脑,你可能熟悉cURL命令行工具,它可以用来从网络下载文件。

pycurllibcurl的Python接口,libcurl是一个强大的HTTP请求工具。它提供了对请求的精细控制,你可以在处理网络资源时将其用于高级用例。

在你的工作环境中安装pycurl可能有些复杂。你可以尝试使用pip安装:

pip install pycurl

⚠️如果在安装过程中遇到错误,请查看PyCURL安装指南获取故障排除提示。

或者,如果你已经安装了cURL,你可以将Python绑定安装到libcurl,如下所示:

sudo apt install python3-pycurl

注意:在安装Python绑定之前,你需要安装cURL。如果你的电脑上没有安装cURL,你可以使用命令:apt install curl

使用PyCURL下载文件

以下是使用PyCURL下载XKCD漫画的代码:

import pycurl
from io import BytesIO

url="https://imgs.xkcd.com/comics/python.png"

c = pycurl.Curl()

c.setopt(pycurl.URL, url)

buffer = BytesIO()
c.setopt(pycurl.WRITEDATA, buffer)

c.perform()

http_code = c.getinfo(pycurl.HTTP_CODE)
if http_code == 200:
    with open('xkcd_comic.png', 'wb') as f:
        f.write(buffer.getvalue())

c.close()

让我们将上述代码拆解成几个步骤:

第1步:导入所需的模块

首先,我们导入pycurl,以便可以使用它来发送HTTP请求。然后,我们从IO模块导入BytesIO,用于创建一个缓冲区来存储下载的数据:

import pycurl
from io import BytesIO

第2步:创建Curl对象并设置URL

我们指定要下载的XKCD Python漫画的URL。然后创建一个curl对象,代表HTTP请求。然后,我们使用c.setopt(pycurl.URL, url)设置Curl对象的URL:

url="https://imgs.xkcd.com/comics/python.png"

c = pycurl.Curl()

c.setopt(pycurl.URL, url)

步骤3:创建BytesIO对象并设置WRITEDATA选项

我们创建一个BytesIO对象来存储下载的数据,并使用c.setopt(pycurl.WRITEDATA, buffer)配置Curl对象将响应数据写入缓冲区:

buffer = BytesIO()
c.setopt(pycurl.WRITEDATA, buffer)

第4步:执行请求

使用c.perform()执行HTTP请求并检索漫画图像数据:

c.perform()

步骤5:检查HTTP状态码并保存下载的数据

我们使用c.getinfo(pycurl.HTTP_CODE)获取HTTP状态码,以确保请求成功(HTTP代码200)。如果HTTP状态码为200,我们将数据从缓冲区写入图像文件:

http_code = c.getinfo(pycurl.HTTP_CODE)
if http_code == 200:
    with open('xkcd_comic.png', 'wb') as f:
        f.write(buffer.getvalue())

第6步:关闭Curl对象

最后,我们使用c.close()关闭curl对象来清理资源:

c.close()

如何以较小的块下载大文件

到目前为止,我们已经了解了将XKCD Python漫画(一个小型图像文件)下载到当前目录的不同方法。

但你可能还需要下载更大的文件,例如IDE的安装程序。下载此类大文件时,以较小的块下载并在下载过程中跟踪进度会很有帮助。为此,我们可以使用requests库的功能。

让我们使用requests下载VS Code安装程序,文件大小约为1MB:

import requests

url="https://code.visualstudio.com/sha/download?build=stable&os=win32-x64-user"

chunk_size = 1024 * 1024  # 1 MB chunks

response = requests.get(url, stream=True)

total_size = int(response.headers.get('content-length', 0))

with open('vs_code_installer.exe', 'wb') as file:
    for chunk in response.iter_content(chunk_size):
        if chunk:
            file.write(chunk)
            file_size = file.tell()
            print(f'Downloading... {file_size}/{total_size} bytes', end='\r')

print('Download complete.')

代码的执行步骤如下:

  • 我们设置chunk_size来确定每个块的大小(本例中为1MB)。
  • 然后,我们使用requests.getstream=True来流式传输响应内容,而无需立即将整个文件加载到内存中。
  • 我们在下载每个块时将其按顺序保存到文件中。

下载过程中,你将看到当前下载的字节数/总字节数:

下载完成后,你将看到”下载完成”的消息:

你将在目录中看到VS Code安装程序:

总结

希望你已经了解了几种使用Python从URL下载文件的不同方法。除了内置的urllib.request外,我们还介绍了流行的第三方Python库,例如requestsurllib3wgetPyCURL

作为一名开发者,我通常在项目中使用requests库来下载文件和使用Web API。但根据下载任务的复杂性和HTTP请求所需的控制级别,其他方法也可能非常有用。下载愉快!