for 循环用法

for 循环是 Python 中最常用的循环语句,它的语法如下:

for i in range(10):
    print(i)

for 循环的问题

for 循环的问题在于,它是顺序执行的,也就是说,当 for 循环中的代码执行完毕后,才会执行下一次循环。这样的话,如果 for 循环中的代码执行时间很长,那么 for 循环的执行时间就会很长。

在我们爬虫的时候,我们经常遇到需要对一个 api 改变一个索引参数进行多次请求,然后拼接数据进行分析。

import requests

url_template = 'https://www.example.com/api?index={index}'

def get_data(index):
    url = url_template.format(index=index)
    response = requests.get(url)
    return response.json()

indexes = [1, 2, 3]
data = []
for index in indexes:
    data.append(get_data(index))

但是,网络访问一直是我们程序执行速度的瓶颈,如果我们使用 for 循环获取数据,那么我们会浪费很多时间。

启用多线程

幸运的是,Python 提供了多线程的支持,我们可以开启多个线程,同时访问多个 url 进行数据获取,这样就节约了很多时间。用下面的语法,可以完美代替 for 循环。

from concurrent.futures import ThreadPoolExecutor

with ThreadPoolExecutor(max_workers=10) as executor:
    results = executor.map(get_data, indexes)
    data = list(results)

多线程提速的原理和注意事项

要注意的是,这个例子使用多线程能够提升执行效率的原因不是因为我们压榨了我们电脑的性能,而是因为我们在下载数据的时候 cpu 其实很空闲,一直在等待下载任务执行完毕,才执行下一次循环的内容(开始下一次的下载)。总而言之,拖慢我们运行速度的是网络,而不是 cpu。因此,如果你的任务主要是本地的计算任务,那么使用多线程并不一定能提升你的运行速度。

另外,同时对一个 api 进行多次请求并不是一个好主意,我们可以控制最大线程数,避免对网络服务器造成过大的压力。