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 模块从 Web 下载文件。