在Python中使用多处理和请求的并行发布请求

qre*_*0ct 6 parallel-processing multiprocessing python-2.7 python-requests grequests

我有一个小代码片段如下:

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()
Run Code Online (Sandbox Code Playgroud)

我所要做的就是将并行POST请求发送到终点,而每个POST都有一个不同的令牌,因为它的帖子正文.

  1. 我能用上面的东西实现我想要的吗?我得到了输出,但我不确定我的请求是否是并行发送的.
  2. 我知道问候.我想实现真正的并行请求(就像在我的系统上使用多个处理器一样),因此我选择了多处理而不是grequests(据我所知,使用gevents,它们同样不是并行的,而是多线程的).我的理解在这里是否正确?

Mat*_*son 8

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

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

2) 是的,你的理解是正确的。我也使用 multiprocessing + requests 组合而不是 grequests。

有关的:

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


Yuv*_*uss 5

如果您对并行执行多个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)
Run Code Online (Sandbox Code Playgroud)

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

  • asyncIO 真的能真正实现并行吗?或者它实际上在幕后做了更多的并发和多线程? (2认同)