使用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.requests
和requests
库的方法更复杂一些。让我们分解一下步骤:
- 我们首先导入
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
命令行工具,它可以用来从网络下载文件。
pycurl是libcurl
的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.get
和stream=True
来流式传输响应内容,而无需立即将整个文件加载到内存中。 - 我们在下载每个块时将其按顺序保存到文件中。
下载过程中,你将看到当前下载的字节数/总字节数:
下载完成后,你将看到”下载完成”的消息:
你将在目录中看到VS Code安装程序:
总结
希望你已经了解了几种使用Python从URL下载文件的不同方法。除了内置的urllib.request
外,我们还介绍了流行的第三方Python库,例如requests
、urllib3
、wget
和PyCURL
。
作为一名开发者,我通常在项目中使用requests
库来下载文件和使用Web API。但根据下载任务的复杂性和HTTP请求所需的控制级别,其他方法也可能非常有用。下载愉快!