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

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

import os
import requests
from time import time
from multiprocessing.pool import ThreadPool

我们导入了 os 和 time 模块来检查下载文件需要多少时间。
ThreadPool 模块允许我们使用池运行多个线程或者进程。

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

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)

URLs 变量是一个二维数组,用于指定要下载的页面的路径和 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 传递给 requests.get。
最后,打开文件(URL 中指定的路径)并写入页面内容。

现在我们可以对每个URL分别调用这个函数,也可以同时对所有的URL调用这个函数。
让我们在 for 循环中分别为每个 URL 执行此操作并设置计时器:

start = time()
for x in urls:
    url_response (x)
print(f"Time to download: {time() - start}")

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

ThreadPool(9).imap_unordered(url_response, urls)

使用 urllib 下载网页

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

urllib 库是 Python 的标准库,无需安装。

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

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

指定下载地址和保存位置。

示例:

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

Python通过代理下载

如果我们需要使用代理来下载文件,我们可以使用 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方法创建了代理对象并打开了代理,并传递了代理对象。
然后我们提出了检索页面的请求。

此外,我们可以使用官方文档中记录的 requests 模块:

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

下载重定向的文件

在本节中,我们将使用requests从重定向URL中下载pdf文件
网址如下所示:

https://testdocs.xx/projects/python-guide/downloads/pdf/latest/

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

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

Python使用异步下载文件

我们可以使用 asyncio 模块来处理系统事件。
它围绕一个事件循环工作,该循环等待事件发生,然后对该事件做出反应。
反应可以是调用另一个函数。
这个过程称为事件处理。
asyncio 模块使用协程进行事件处理。

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

import asyncio

另外,我们需要安装 aiohttp 模块。

pip install aiohttp

我们将导入 async_timeout 模块来处理超时。

import async_timeout

关键字 async 表明这是一个原生的 asyncio 协程。
在协程的主体内部,我们有 await 关键字,它返回某个值。
我们还使用了 return 关键字。

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

import asyncio
import uuid
import aiohttp
import async_timeout
async def get_url(url, session):

    file_name = str(uuid.uuid4())

    async with async_timeout.timeout(120):

        async with session.get(url) as response:

            with open(file_name, 'wb') as fd:

                async for data in response.content.iter_chunked(1024):

                    fd.write(data)
    return 'Successfully downloaded ' + file_name
async def main(urls):

    async with aiohttp.ClientSession() as session:

        tasks = [get_url(url, session) for url in urls]
        return await asyncio.gather(*tasks)
urls = ["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/"]
loop = asyncio.get_event_loop()
results = loop.run_until_complete(main(urls))
print('\n'.join(results))

使用请求

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

考虑下面的代码:

import requests
url = 'https://www.python.org/static/img/jack@onitroad'
myfile = requests.get(url)
open('c:/users/onitroad/downloads/PythonImage.png', 'wb').write(myfile.content)

简单地说,使用 requests 模块的 get 方法获取 URL 并将结果存储到变量“myfile”变量中。
然后将变量的内容写入文件。

使用 urllib3 下载文件

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

pip install urllib3

我们将使用 urllib3 获取网页并将其存储在文本文件中。

导入以下模块:

import urllib3, shutil

我们可以在处理文件时使用shutil 模块。
现在像这样初始化 URL 字符串变量:

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

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

c = urllib3.PoolManager()

创建一个文件:

filename = "test.txt"

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

with c.request('GET', url, preload_content=False) as res, open(filename, 'wb') as out_file:
	shutil.copyfileobj(res, out_file)

Python分块下载大文件

考虑代码:

import requests
url = 'https://www.cs.uky.edu/~keen/115/Haltermanpythonbook.pdf'
r = requests.get(url, stream = True)
with open("PythonBook.pdf", "wb") as Pypdf:
	for chunk in r.iter_content(chunk_size = 1024):
		if chunk:
			Pypdf.write(chunk)

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

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

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

使用 wget

我们还可以使用 Python 的 wget 模块从 URL 下载文件。
使用 pip 安装 wget 模块,如下所示:

pip install wget

以下代码,我们将其中下载 Python 的logo图片:

import wget
url = "https://www.python.org/static/img/pythonLogo.png"
wget.download(url, 'c:/users/onitroad/downloads/pythonLogo.png')

Python带进度条下载

进度条是 clint 模块的 UI 小部件。
要安装 clint 模块,执行以下命令:

pip install clint

考虑以下代码:

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)
使用 Python 下载文件示例

在本教程中,我们将学习如何使用不同的 Python 模块从 Web 下载文件。

日期:2020-07-15 11:16:26 来源:oir作者:oir