Помогите разобраться с многопроцессорностью

import requests
from multiprocessing import Pool
headers =0
cookies = 0
def get_data(url,headers, cookies):
    r = requests.get(url)
    print('1')


if __name__ == '__main__':
    p  = Pool(processes=3)
    urls = ['https://vk.com/feed', 'https://vk.com/feed', 'https://vk.com/feed']
    p.map(get_data, urls)

Это простой код для наглядности. Мне интересно как я должен передать headers и cookies если надо. При запуске ошибка: get_data() missing 2 required positional arguments: 'headers' and 'cookies'. Если я их определяю то будет не определено url.


Ответы (2 шт):

Автор решения: eri

Или функтулс и ключевые аргументы, стандарт

import requests
from multiprocessing import Pool
import functools

headers = 0
cookies = 0

def get_data(url,headers=None, cookies=None):
    r = requests.get(url,headers=headers, cookies=cookies)
    print('1')


if __name__ == '__main__':
    p  = Pool(processes=3)
    urls = ['https://vk.com/feed', 'https://vk.com/feed', 'https://vk.com/feed']
    p.map(functools.partial(get_data, headers=headers, cookies=cookies), urls)

Или безимяная функция, аргументы передаются через замыкание

import requests
from multiprocessing import Pool

headers = 0
cookies = 0

def get_data(url,headers, cookies):
    r = requests.get(url,headers=headers, cookies=cookies)
    print('1')


if __name__ == '__main__':
    p  = Pool(processes=3)
    urls = ['https://vk.com/feed', 'https://vk.com/feed', 'https://vk.com/feed']
    p.map(lambda url: get_data(url, headers, cookies), urls)

Или обычная функция, аргументы в глобале

import requests
from multiprocessing import Pool

headers = 0
cookies = 0

def get_data(url,headers, cookies):
    r = requests.get(url,headers=headers, cookies=cookies)
    print('1')

def get_data_with_headers(url):
    return get_data(url,headers, cookies)

if __name__ == '__main__':
    p  = Pool(processes=3)
    urls = ['https://vk.com/feed', 'https://vk.com/feed', 'https://vk.com/feed']
    p.map(get_data_with_headers, urls)

Или карирование, аргументы в контексте функции, тоже что и functools, только сделано вручную (удобно когда надо воткнуть несколько операций)

import requests
from multiprocessing import Pool

headers = 0
cookies = 0

def get_data(url,headers, cookies):
    r = requests.get(url,headers=headers, cookies=cookies)
    print('1')

def get_data_with_headers(headers, cookies):
    def get_data_internal(url):
        return get_data(url,headers, cookies)
    return get_data_internal

if __name__ == '__main__':
    p  = Pool(processes=3)
    urls = ['https://vk.com/feed', 'https://vk.com/feed', 'https://vk.com/feed']
    p.map(get_data_with_headers(headers, cookies), urls)
→ Ссылка
Автор решения: Stanislav Volodarskiy

Передайте все необходимые данные в кортежах:

import requests
from multiprocessing import Pool


def get_data(url, headers, cookies):
    r = requests.get(url)
    print('1')


def get_data_for_map(record):
    url, headers, cookies = record
    get_data(url, headers, cookies)


if __name__ == '__main__':

    urls = ['https://vk.com/feed', 'https://vk.com/feed', 'https://vk.com/feed']
    headers = 0
    cookies = 0

    records = [(url, headers, cookies) for url in urls]

    p  = Pool(processes=3)
    p.map(get_data_for_map, records)

Приём такой удобный что для него есть starmap:

import requests
from multiprocessing import Pool


def get_data(url, headers, cookies):
    r = requests.get(url)
    print('1')


if __name__ == '__main__':

    urls = ['https://vk.com/feed', 'https://vk.com/feed', 'https://vk.com/feed']
    headers = 0
    cookies = 0

    records = [(url, headers, cookies) for url in urls]

    p  = Pool(processes=3)
    p.starmap(get_data, records)
→ Ссылка