无法使用 concurrent.futures 加速脚本的执行过程

Posted

技术标签:

【中文标题】无法使用 concurrent.futures 加速脚本的执行过程【英文标题】:Failed to speed up the execution process of a script using concurrent.futures 【发布时间】:2022-01-09 14:26:21 【问题描述】:

我正在尝试在以下脚本中实现concurrent.futures 或类似的东西,以加快执行速度。但是,当我比较这两个脚本时,我发现速度没有变化。为了达到同样的效果,我应该带来哪些可能的改变?

原文:

import requests
from bs4 import BeautifulSoup


link = 'https://ldc.lloyds.com/market-directory/results'

params = 
    'cobc': '','cob': '','loc': '','ltti': '',
    'bro': '0','cov': '1','man': '0','mem': '0',
    'omc': '0','run': '0','name': '','mode':' cov',
    'c_page': 1 #---------------->unknown number of pages to traverse


def get_content(s,link,params):
    while True:
        r = s.get(link,params=params)
        soup = BeautifulSoup(r.text,"lxml")
        if not soup.select(".marketing-directories-results .contact-details > h2"): 
            return

        for item in soup.select(".marketing-directories-results .contact-details > h2"):
            yield item.text

        params['c_page']+=1

if __name__ == '__main__':
    with requests.Session() as s:
        s.headers['User-Agent'] = 'Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (Khtml, like Gecko) Chrome/88.0.4324.104 Safari/537.36'
        for item in get_content(s,link,params):
            print(item)

当我在脚本中实现concurrent.futures 时,我在执行过程中看不到任何与速度相关的改进:

import requests
from bs4 import BeautifulSoup
import concurrent.futures as futures

link = 'https://ldc.lloyds.com/market-directory/results'

params = 
    'cobc': '','cob': '','loc': '','ltti': '',
    'bro': '0','cov': '1','man': '0','mem': '0',
    'omc': '0','run': '0','name': '','mode':' cov',
    'c_page': 1  #---------------->unknown number of pages to traverse


def get_content(s,link,params):

    while True:
        item_list = []
        r = s.get(link,params=params)
        soup = BeautifulSoup(r.text,"lxml")
        if not soup.select(".marketing-directories-results .contact-details > h2"): 
            return

        for item in soup.select(".marketing-directories-results .contact-details > h2"):
            print(item.text)

        params['c_page']+=1
        

if __name__ == '__main__':
    with requests.Session() as s:
        s.headers['User-Agent'] = 'Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.104 Safari/537.36'

        with futures.ThreadPoolExecutor(max_workers=5) as executor:
            future_to_url = executor.submit(get_content, s, url, params): url for url in [link]
            futures.as_completed(future_to_url)

如何实现concurrent.futures 或类似的东西来加快执行速度?

【问题讨论】:

您正在实例化一个线程。在这种情况下这无济于事。事实上,它可能比同步运行函数稍微慢一些(由于线程池构造等)。如果您有多个 URL 来收集数据,那么多线程将是合适的 【参考方案1】:

在您的示例中,您将link url 变量作为executor.submit 函数的参数中的列表传递。它将被视为['h','t','t','p',.. so on]

我建议这样实现:

import concurrent.futures as futures
from functools import partial

thread_func = partial(get_content,s, url)
with concurrent.futures.ThreadPoolExecutor(max_worker=5) as pool:
    result = pool.map(thread_func, params)

我使用部分函数只是为了清楚在 map 函数中作为迭代器参数传递的内容。

希望这对您有所帮助。

【讨论】:

以上是关于无法使用 concurrent.futures 加速脚本的执行过程的主要内容,如果未能解决你的问题,请参考以下文章

创建进程池与线程池concurrent.futures模块的使用

为啥我不能在类方法中使用 python 模块 concurrent.futures?

Python学习第25篇:concurrent.futures模块(进程池,线程池)

python concurrent.futures

python全栈开发基础第二十六篇(concurrent.futures模块协程GreenletGevent)

Python:concurrent.futures 如何使其可取消?