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 下载文件。
