【问题标题】:Speed up Python Request from csv list加快来自 csv 列表的 Python 请求
【发布时间】:2019-12-01 19:57:12
【问题描述】:

如下所示的 Python 新手是我的第一次尝试。我拥有的是一个列出客户工作编号的 csv 文件。我正在对我们的(第三方)工作管理系统进行 3 次 api 调用。 1 获取实际作业编号,2 获取作业阶段,3 获取作业状态(如下)。我有一个 vb.net 应用程序,可以将这些结果全部分开,将它们与其他数据混合,并将它们添加到 MYSQL 数据中,以便在 Ruby 仪表板上进行报告等。Grunt 与 API 调用的工作是在 excel vba 中完成的,因为我可以做到这一切都在一个地方。 API 调用很慢,非常慢,所以我想办法加快速度,然后 Python 出现了。排序下面以及从.net调用它,但它仍然很慢。这三个电话总共需要大约 5 分钟。我们只查看大约 60 到 70 个工作编号。第一次调用工作编号确实会带来一个大的 json 文件,但不幸的是不是我在第二次和第三次调用中需要的数据,所以我无法通过消除 2 和 3 来加速它。

由于我刚开始接触 Python,我无法轻易找到解决方案。我一直在看多线程、多处理的帖子,但都是有半点线索的人问的,我还没有。

非常感谢任何帮助。

import requests
import csv


with open("C:\\******.csv") as csvfile:
    readCSV = csv.reader(csvfile, delimiter=",")
    jobs = []
    Stages = []
    outfile = open("C:\\*********another****.csv", "w")
    for row in readCSV:
        job = row[0]
        url = (
            "https:/********.com/api/v1.0/companies/**/jobs/"
            + job
            + "?columns=Status"
        )
        auth_token = "*******"

        payload = ""
        headers = {
            "Content-Type": "application/json x-www-form-urlencoded",
            "Authorization": "Bearer *********",
            "Accept": "*/*",
            "Cache-Control": "no-cache",
            "Host": "*****",
            "Accept-Encoding": "gzip, deflate",
            "Connection": "keep-alive",
            "cache-control": "no-cache",
        }

        response = requests.request(
            "GET", url, data=payload, headers=headers
        )
        Stage = response.text

        print((job, Stage), file=outfile)

    outfile.close

【问题讨论】:

  • 您的代码仅显示发出一个GET 请求。所有 3 个请求都需要按顺序发生吗?顺便说一句,您正在寻找多线程而不是多处理,因为这是一个 I/O 绑定任务
  • @aws_apprentice 代码对每个从 CSV 文件读取的job 执行一个 GET 请求,因此发生的请求与 CSV 文件中的行数一样多。
  • 这三个中的每一个都非常相似,并且 Status 和 Stage 调用是相同的。对工作编号的第一次调用被拉开以获取第二次和第三次调用的数据。 1 和 2 以及 2 和 3 之间存在延迟,因此可以对生成的文件进行其他处理。这实际上只是每个单独请求所需的时间,这是我第一次尝试,因此我希望能够针对其他两个请求提供一些建议和指导。

标签: python multithreading python-requests


【解决方案1】:

这样的事情应该让您获得多处理工作。

我们的想法是将 CSV 中的作业重构为一个生成器函数,然后将访问 API 的函数重构为另一个。

(由于您显然在 Windows 上,因此您需要使用 main() 函数和 if main 防护与 multiprocessing。)

import requests
import csv
import multiprocessing

sess = requests.Session()

headers = {
    "Accept": "*/*",
    "Accept-Encoding": "gzip, deflate",
    "Authorization": "Bearer *********",
    "Cache-Control": "no-cache",
    "Host": "*****",
}


def read_jobs():
    with open("C:\\******.csv") as csvfile:
        for row in csv.reader(csvfile, delimiter=","):
            yield row[0]


def get_job_status(job):
    url = (
        "https:/********.com/api/v1.0/companies/**/jobs/"
        + job
        + "?columns=Status"
    )
    response = requests.request(
        method="GET", url=url, headers=headers
    )
    print("Got job ", job)
    return (job, response.text)


def main():
    with open("C:\\*********another****.csv", "w") as outfile:
        with multiprocessing.Pool() as pool:
            for result in pool.imap_unordered(
                get_job_status, read_jobs()
            ):
                print(result, file=outfile)


if __name__ == "__main__":
    main()

【讨论】:

  • 感谢 AKX,它确实为事情增加了一些节奏,让我有机会积累一些知识。非常感谢。
【解决方案2】:

多处理取决于核心数量。在您的情况下,您需要线程。线程最简单的接口是 ThreadPool。例如:

from multiprocessing.pool import ThreadPool

threads_count = 10
pool = ThreadPool(threads_count)

def do_job(url)
    return requests.get(url)

urls = ['url1', 'url2']

pool.map(do_job, urls)

pool.close()
pool.join()

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-07-07
    • 2020-04-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多