在本教程中,您将学习如何使用不同的Python模块从Web上下载文件。还可以下载常规文件、网页、Amazon S3和其他来源。

最后,还会学习到如何克服可能遇到的各种挑战,例如下载重定向文件、下载大文件、完成多线程下载以及其他策略。

使用请求

您可以使用请求模块从URL下载文件。

可以使用下面的代码:

importrequests
url = 'https: //www.python.org/static/img/python-logo@2x.png'
myfile = requests. get(url)
open(' c:/users/ LikeGeeks/downloads/ PythonImage.png', 'wb').write(myfile.content)

只需使用请求模块的get方法获取URL,然后将结果存储到名为“ myfile”的变量中即可。然后,将变量的内容写入文件。

使用wget

您还可以使用Python的wget模块从URL下载文件。wget模块可以使用以下pip进行安装:

pipinstall wget

看看以下代码,我们将下载Python的图像:

importwget
url = "https://www.python.org/static/img/python-logo@2x.png"
wget.download(url, ' c:/users/ LikeGeeks/downloads/pythonLogo.png')

在此代码中,URL以及路径(将存储图像的路径)将传递到wget模块的下载方法。

下载重定向文件

在本节中,您将学习如何从URL下载,该URL使用请求将.pdf文件重定向到另一个URL。该URL的地址如下:

https:/ /readthedocs.org/projects/python-guide/downloads/pdf/latest/

要下载此pdf文件,请使用以下代码:

importrequests
url = 'https: //readthedocs.org/projects/python-guide/downloads/pdf/latest/'
myfile = requests. get(url, allow_redirects= True)
open(' c:/users/ LikeGeeks/documents/hello.pdf', 'wb').write(myfile.content)

在此代码中,我们指定的第一步是URL。然后,我们使用请求模块的get方法来获取URL。在get方法中,我们将allow_redirects设置为True,也就是说允许在URL中进行重定向,并且重定向后的内容将分配给变量myfile。

最后,我们打开一个文件来写入获取的内容。

下载大文件块

可以看下面的代码:

importrequests
url = 'https: //www.python.org/static/img/python-logo@2x.png'
myfile = requests. get(url)
open(' c:/users/ LikeGeeks/downloads/ PythonImage.png', 'wb').write(myfile.content)

首先,我们像以前一样使用requests模块的get方法,但是这次,我们将stream属性设置为True。

然后,在当前工作目录中创建一个名为PythonBook.pdf的文件并打开它进行编写。

我们指定每次要下载的块大小。我们将其设置为1024个字节,遍历每个块,然后将这些块写入文件中,直到块完成为止。

不用担心,稍后我们将显示进度条以供下载。

要一次下载多个文件,请导入以下模块:

importos
importrequests
from time importtime
from multiprocessing.pool importThreadPool

我们导入了os和time模块,以检查下载文件需要花费多少时间。ThreadPool模块使您可以使用池运行多个线程或进程。

让我们创建一个简单的函数,将响应分块发送到一个文件的块:

defurl_response(url):
path, url = url
r = requests.get(url, stream = True)
withopen(path, 'wb') asf:
forch inr:
f.write(ch)

URL是一个二维数组,用于指定要下载的页面的路径和URL。

urls = [( "Event1", "https://www.python.org/events/python-events/805/"),
( "Event2", "https://www.python.org/events/python-events/801/"),
( "Event3", "https://www.python.org/events/python-events/790/"),
( "Event4", "https://www.python.org/events/python-events/798/"),
( "Event5", "https://www.python.org/events/python-events/807/"),
( "Event6", "https://www.python.org/events/python-events/807/"),
( "Event7", "https://www.python.org/events/python-events/757/"),
( "Event8", "https://www.python.org/events/python-user-group/816/")]

如上一节所述,将URL传递给request.get。最后,打开文件(URL中指定的路径)并编写页面内容。

现在,我们可以分别为每个URL调用此函数,也可以同时为所有URL调用此函数。让我们分别在for循环中为每个URL进行操作,注意计时器:

start = time
forx inurls:
url_response (x)
print( f"Time to download: {time - start}")

现在,用以下代码替换for循环:

ThreadPool(9) .imap_unordered( url_response, urls)

运行脚本

下载进度条

进度条是客户端模块的UI小部件。要安装客户端模块,请键入以下命令:

pipinstall clint

看下以下代码:

importrequests
from clint.textui importprogress
url = 'http: //do1.dr-chuck.com/pythonlearn/EN_us/pythonlearn.pdf'
r = requests. get(url, stream= True)
with open( "LearnPython.pdf", "wb") asPypdf:
total_length = int(r.headers. get('content-length'))
forch inprogress.bar(r.iter_content(chunk_size = 2391975), expected_size=(total_length/ 1024) + 1):
ifch:
Pypdf.write(ch)

在这段代码中,我们导入了请求模块,然后从clint.textui中导入了进度小部件。唯一的区别在于for循环。在将内容写入文件时,我们使用了进度模块的bar方法。

使用urllib下载网页

在本节中,我们将使用urllib下载一个网页。

urllib库是Python的标准库,因此您无需安装它。

以下代码行可以轻松下载网页:

urllib.request.urlretrieve( 'url', 'path')

在此处指定要保存的URL,以及要在其中存储的URL:

urllib.request.urlretrieve( 'https://www.python.org/', 'c:/users/LikeGeeks/documents/PythonOrganization.html')

在这段代码中,我们使用了urlretrieve方法,并传递了文件的URL以及保存文件的路径,文件扩展名为.html。

通过代理下载

如果您需要使用代理来下载文件,则可以使用urllib模块的ProxyHandler。检查以下代码:

import urllib.request
>>> myProxy = urllib.request.ProxyHandler({ 'http': '127.0.0.2'})
>>> openProxy = urllib.request.build_opener(myProxy)
>>> urllib.request.urlretrieve( 'https://www.python.org/')

在此代码中,我们创建了代理对象,并通过调用urllib的build_opener方法打开了代理,并传递了代理对象。然后,我们提出了检索页面的请求。

另外,您还可以使用官方文档中记录的请求模块:

importrequests
myProxy = { 'http': 'http: //127.0.0.2:3001' }
requests. get( "https://www.python.org/", proxies=myProxy)

只需导入请求模块并创建您的代理对象,然后,您可以检索该文件。

使用urllib3

urllib3是urllib模块的改进版本。您可以使用pip下载并安装它:

pipinstall urllib3

我们将获取一个web页面,并使用urllib3将其存储在文本文件中。

导入以下模块:

importurllib3, shutil

当处理文件时,将使用shutil模块。

现在,像这样初始化URL字符串变量:

url= 'https://www.python.org/'

然后,我们使用urllib3的PoolManager来跟踪必要的连接池。

创建一个文件:

c= urllib3.PoolManager

最后,我们发送GET请求以获取URL并打开一个文件,将响应写入该文件:

withc.request( 'GET', url, preload_content= False) asres, open(filename, 'wb') asout_file:
shutil.copyfileobj(res, out_file)

使用Boto3从S3下载文件

要从Amazon S3下载文件,您可以使用Python boto3模块。

在开始之前,您需要使用pip安装awscli模块:

pipinstall awscli

对于AWS配置,运行以下命令:

awsconfigure

现在,输入您的详细信息为:

AWSAccessKeyID[None]: ( Theaccesskey)
AWSSecretAccessKey[None]: ( Secretaccesskey)
Defaultregionname[None]: ( Region)
Defaultoutputformat[None]: ( Json)

要从Amazon S3下载文件,需要导入boto3和botocore。Boto3是用于Python的Amazon SDK,用于访问Amazon Web服务(例如S3)。Botocore提供了与Amazon Web服务进行交互的命令行服务。

Botocore自带awscli。要安装boto3,请运行以下命令:

pipinstall boto3

现在,导入以下两个模块:

importboto3, botocore

从亚马逊下载文件时,我们需要三个参数:

Bucket的名字

您需要下载的文件的名称

下载后的文件名

初始化变量:

bucket= "bucketName"
file_name= "filename"
downloaded_file= "downloadedfilename"

现在,初始化一个变量以使用会话资源。为此,我们将调用boto3的resource方法并传递服务,即s3:

service= boto3.resource(‘s3’)

最后,使用download_file方法下载文件并传递变量:

service.Bucket( bucket) .download_file( file_name, downloaded_file)

使用asyncio

asyncio模块专注于处理系统事件。它围绕一个事件循环工作,该事件循环等待事件发生,然后对该事件做出反应。这个反应可能是调用另一个函数,此过程称为even handling。asyncio模块使用协同程序进行事件处理。

要使用asyncio事件处理和协程工作的功能,我们将导入asyncio模块:

importasyncio

现在,定义如下所示的asyncio coroutine方法:

asyncdefcoroutine:
awaitmy_func

关键字async表示这是一个本地asyncio协程。在协程的主体内部,我们有一个await关键字,该关键字返回某个特定值。还可以使用return关键字。

现在,让我们使用协程创建代码以从网络下载文件:

>>>importos
>>>importurllib.request
>>>asyncdefcoroutine(url):
r = urllib.request.urlopen(url)
filename = "couroutine_downloads.txt"
withopen(filename, 'wb') asf:
forch inr:
f.write(ch)
print_msg = 'Successfully Downloaded'
returnprint_msg
>>>asyncdefmain_func(urls_to_download):
co = [coroutine(url) forurl inurls_to_download]
downloaded, downloading = awaitasyncio.wait(co)
fori indownloaded:
print(i.result)
urls_to_download = [ "https://www.python.org/events/python-events/801/",
"https://www.python.org/events/python-events/790/",
"https://www.python.org/events/python-user-group/816/",
"https://www.python.org/events/python-events/757/"]
>>>eventLoop = asyncio.get_event_loop
>>>eventLoop.run_until_complete(main_func(urls_to_download))

在此代码中,我们创建了一个异步协程函数,该函数会下载文件并返回一条消息。

然后,我们有另一个异步协程调用main_func,它等待URL并将所有URL组成一个队列。

现在要启动协程,我们必须使用asyncio的get_event_loop方法将协程放入事件循环中,最后,使用asyncio的run_until_complete方法执行事件循环。

使用Python下载文件 是一次有趣的尝试,你们也可以试试看。