前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >使用Python下载文件的简单示例

使用Python下载文件的简单示例

作者头像
用户6543014
发布2020-03-31 10:34:07
8.3K0
发布2020-03-31 10:34:07
举报
文章被收录于专栏:CU技术社区CU技术社区

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

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

使用请求

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

可以使用下面的代码:

代码语言:javascript
复制
import requests
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进行安装:

代码语言:javascript
复制
pip install wget

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

代码语言:javascript
复制
import wget
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的地址如下:

代码语言:javascript
复制
https://readthedocs.org/projects/python-guide/downloads/pdf/latest/

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

代码语言:javascript
复制
import requests
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。

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

下载大文件块

可以看下面的代码:

代码语言:javascript
复制
import requests
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个字节,遍历每个块,然后将这些块写入文件中,直到块完成为止。

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

下载多个文件(并行/批量下载)

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

代码语言:javascript
复制
import os
import requests
from time import time
from multiprocessing.pool import ThreadPool

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

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

代码语言:javascript
复制
def url_response(url):
    path, url = url
    r = requests.get(url, stream = True)
    with open(path, 'wb') as f:
        for ch in r:
            f.write(ch)

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

代码语言:javascript
复制
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进行操作,注意计时器:

代码语言:javascript
复制
start = time()
for x in urls:
    url_response (x)
print(f"Time to download: {time() - start}")

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

代码语言:javascript
复制
ThreadPool(9).imap_unordered(url_response, urls)

运行脚本

下载进度条

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

代码语言:javascript
复制
pip install clint

看下以下代码:

代码语言:javascript
复制
import requests
from clint.textui import progress
url = 'http://do1.dr-chuck.com/pythonlearn/EN_us/pythonlearn.pdf'
r = requests.get(url, stream=True)
with open("LearnPython.pdf", "wb") as Pypdf:
    total_length = int(r.headers.get('content-length'))
    for ch in progress.bar(r.iter_content(chunk_size = 2391975), expected_size=(total_length/1024) + 1):
        if ch:
            Pypdf.write(ch)

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

使用urllib下载网页

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

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

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

代码语言:javascript
复制
urllib.request.urlretrieve('url', 'path')

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

代码语言:javascript
复制
urllib.request.urlretrieve('https://www.python.org/', 'c:/users/LikeGeeks/documents/PythonOrganization.html')

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

通过代理下载

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

代码语言:javascript
复制
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方法打开了代理,并传递了代理对象。然后,我们提出了检索页面的请求。

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

代码语言:javascript
复制
import requests
myProxy = { 'http': 'http://127.0.0.2:3001' }
requests.get("https://www.python.org/", proxies=myProxy)

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

使用urllib3

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

代码语言:javascript
复制
pip install urllib3

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

导入以下模块:

代码语言:javascript
复制
import urllib3, shutil

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

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

代码语言:javascript
复制
url = 'https://www.python.org/'

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

创建一个文件:

代码语言:javascript
复制
c = urllib3.PoolManager()

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

代码语言:javascript
复制
with c.request('GET', url, preload_content=False) as res, open(filename, 'wb') as out_file:
    shutil.copyfileobj(res, out_file)

使用Boto3从S3下载文件

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

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

代码语言:javascript
复制
pip install awscli

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

代码语言:javascript
复制
aws configure

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

代码语言:javascript
复制
AWS Access Key ID [None]: (The access key)
AWS Secret Access Key [None]: (Secret access key)
Default region name [None]: (Region)
Default output format [None]: (Json)

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

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

代码语言:javascript
复制
pip install boto3

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

代码语言:javascript
复制
import boto3, botocore

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

  1. Bucket的名字
  2. 您需要下载的文件的名称
  3. 下载后的文件名

初始化变量:

代码语言:javascript
复制
bucket = "bucketName"
file_name = "filename"
downloaded_file = "downloadedfilename"

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

代码语言:javascript
复制
service = boto3.resource(‘s3’)

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

代码语言:javascript
复制
service.Bucket(bucket).download_file(file_name, downloaded_file)

使用asyncio

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

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

代码语言:javascript
复制
import asyncio

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

代码语言:javascript
复制
async def coroutine():
    await my_func()

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

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

代码语言:javascript
复制
>>> import os
>>> import urllib.request
>>> async def coroutine(url):
    r = urllib.request.urlopen(url)
    filename = "couroutine_downloads.txt"
    with open(filename, 'wb') as f:
        for ch in r:
            f.write(ch)
    print_msg = 'Successfully Downloaded'
    return print_msg
>>> async def main_func(urls_to_download):
    co = [coroutine(url) for url in urls_to_download]
    downloaded, downloading = await asyncio.wait(co)
    for i in downloaded:
        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下载文件 是一次有趣的尝试,你们也可以试试看。

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2020-03-27,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 SACC开源架构 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档