【问题标题】:parallel post requests using multiprocessing and requests in Python使用多处理的并行发布请求和 Python 中的请求
【发布时间】:2017-04-17 08:40:28
【问题描述】:

我有如下小代码sn-p:

import requests
import multiprocessing

header = {
'X-Location': 'UNKNOWN',
'X-AppVersion': '2.20.0',
'X-UniqueId': '2397123',
'X-User-Locale': 'en',
'X-Platform': 'Android',
'X-AppId': 'com.my_app',
'Accept-Language': 'en-ID',
'X-PushTokenType': 'GCM',
'X-DeviceToken': 'some_device_token'
}


BASE_URI = 'https://my_server.com/v2/customers/login'

def internet_resource_getter(post_data):
    stuff_got = []

    response = requests.post(BASE_URI, headers=header, json=post_data)
    stuff_got.append(response.json())

    return stuff_got

tokens = [{"my_token":'EAAOZAe8Q2rKYBAu0XETMiCZC0EYAddz4Muk6Luh300PGwGAMh26Bpw3AA6srcxbPWSTATpTLmvhzkUHuercNlZC1vDfL9Kmw3pyoQfpyP2t7NzPAOMCbmCAH6ftXe4bDc4dXgjizqnudfM0D346rrEQot5H0esW3RHGf8ZBRVfTtX8yR0NppfU5LfzNPqlAem9M5ZC8lbFlzKpZAZBOxsaz'},{"my_token":'EAAOZAe8Q2rKYBAKQetLqFwoTM2maZBOMUZA2w5mLmYQi1GpKFGZAxZCaRjv09IfAxxK1amZBE3ab25KzL4Bo9xvubiTkRriGhuivinYBkZAwQpnMZC99CR2FOqbNMmZBvLjZBW7xv6BwSTu3sledpLSGQvPIZBKmTv3930dBH8lazZCs3q0Q5i9CZC8mf8kYeamV9DED1nsg5PQZDZD'}]

pool = multiprocessing.Pool(processes=3)
pool_outputs = pool.map(internet_resource_getter, tokens)
pool.close()
pool.join()

我要做的就是将并行 POST 请求发送到端点,而每个 POST 将具有不同的标记,因为它是 post 正文。

  1. 我能用上面的方法实现我想要的吗?我得到了输出,但不确定我的请求是否是并行发送的。
  2. 我知道 grequests。我想实现真正的并行请求(如在我的系统上使用多个处理器),因此我选择了多处理而不是 grequests(据我所知,它使用 gevents,它又不是并行的,而是多线程的)。我的理解是否正确?

【问题讨论】:

    标签: python-2.7 parallel-processing multiprocessing python-requests grequests


    【解决方案1】:

    如果你对并行执行多个 POST 请求感兴趣,我建议你使用asyncioaiohttp,它们都实现了异步任务的思想,并行运行。

    例如,您可以使用asyncio 执行类似的操作:

    import requests
    import asyncio
    
    header = {
        'X-Location': 'UNKNOWN',
        'X-AppVersion': '2.20.0',
        'X-UniqueId': '2397123',
        'X-User-Locale': 'en',
        'X-Platform': 'Android',
        'X-AppId': 'com.my_app',
        'Accept-Language': 'en-ID',
        'X-PushTokenType': 'GCM',
        'X-DeviceToken': 'some_device_token'
    }
    
    BASE_URI = 'https://my_server.com/v2/customers/login'
    
    
    def internet_resource_getter(post_data):
        stuff_got = []
    
        response = requests.post(BASE_URI, headers=header, json=post_data)
    
        stuff_got.append(response.json())
        print(stuff_got)
        return stuff_got
    
    tokens = [
        {
            "my_token": 'EAAOZAe8Q2rKYBAu0XETMiCZC0EYAddz4Muk6Luh300PGwGAMh26B'
                        'pw3AA6srcxbPWSTATpTLmvhzkUHuercNlZC1vDfL9Kmw3pyoQfpyP'
                        '2t7NzPAOMCbmCAH6ftXe4bDc4dXgjizqnudfM0D346rrEQot5H0es'
                        'W3RHGf8ZBRVfTtX8yR0NppfU5LfzNPqlAem9M5ZC8lbFlzKpZAZBO'
                        'xsaz'
         },
        {
            "my_token": 'EAAOZAe8Q2rKYBAKQetLqFwoTM2maZBOMUZA2w5mLmYQi1GpKFGZAx'
                        'ZCaRjv09IfAxxK1amZBE3ab25KzL4Bo9xvubiTkRriGhuivinYBkZA'
                        'wQpnMZC99CR2FOqbNMmZBvLjZBW7xv6BwSTu3sledpLSGQvPIZBKmT'
                        'v3930dBH8lazZCs3q0Q5i9CZC8mf8kYeamV9DED1nsg5PQZDZD'
         }
    ]
    
    loop = asyncio.get_event_loop()
    
    for token in tokens:
        loop.run_in_executor(None, internet_resource_getter, token)
    

    请注意:它们只存在于python 3.x。但是,在我看来,它看起来更好更简洁,并且确保它们并行运行。

    【讨论】:

    • asyncIO 真的能真正实现并行吗?或者它实际上在底层做了更多的并发和多线程?
    【解决方案2】:

    1) 是的,上面的代码将对每个令牌发出请求。检查请求是否被正确处理的一种方法是检查返回码:

    for response in pool_outputs:
       if response.status_code != 200:
           raise Exception("{} - {}".format(response.status_code, response.text))
    

    2) 是的,您的理解是正确的。我也使用多处理 + 请求组合而不是 grequests。

    相关:

    通常在发出并行请求时,您无需专注于使用多个内核,除非您发出数百万个请求。这是因为 HTTP 请求需要 99% 的 Internet 响应时间和 1% 的 CPU 处理时间。您的代码将同时发送多个请求,这才是真正重要的。此外,您可能需要查看可怕的 GlobalInterpreterLock 以查看它是否会影响您的多核应用程序:What is a global interpreter lock (GIL)?

    【讨论】:

    • 所以您可以使用此方法重试...是否有安全的数据结构可用于对失败的请求进行重试?我对 Python 不是很熟悉,主要是做 C++ 线程代码。
    猜你喜欢
    • 2015-06-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多