Как сохранять файл в openpyxl в мультипроцессорности?

Код:

from multiprocessing import Pool
from openpyxl import Workbook
import requests
from bs4 import BeautifulSoup
headers = {'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.83 Safari/537.36'}
wb = Workbook()
wb.remove(wb.active)
ws = wb.create_sheet('habr')
ws.append(['name'])


def get_data(url, headers):
    r = requests.get(url)
    soup = BeautifulSoup(r.text, 'lxml')
    name = soup.find('h1', class_='tm-article-snippet__title tm-article-snippet__title_h1').find('span').text # Получение названия статьи
    ws.append([name]) 


def main():
    urls = ['https://habr.com/ru/company/otus/blog/596071/'] * 3
    records = [(url, headers) for url in urls] # Создание итерируемых объектов
    with Pool(3) as p:
        p.starmap(get_data, records)
    wb.save('test.xlsx') # Сохранение файла

if __name__ == '__main__':
    main()

На выходе пустой файл xlsx. Только заголовок есть. Мне говорили что надо использовать Pipe() или Queue(), но я вообще не понимаю как они должны работать.


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

Автор решения: Сергей Ш

Ну как-то так:

from multiprocessing import Pool
from openpyxl import Workbook
import requests
from bs4 import BeautifulSoup

headers = {'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko)'
                         ' Chrome/85.0.4183.83 Safari/537.36'
           }
wb = Workbook()
wb.remove(wb.active)
ws = wb.create_sheet('habr')
ws.append(['name', 'status_code'])
urls = ['https://habr.com/ru/company/otus/blog/596071/',
        'https://habr.com/ru/company/otus/blog/666862/',
        'https://habr.com/ru/company/otus/blog/666830/',
        'https://habr.com/ru/company/otus/blog/666858/',
        'https://habr.com/ru/company/otus/blog/666678/'
        ]

def get_data(url, headers):
    r = requests.get(url)
    soup = BeautifulSoup(r.text, 'lxml')
    name = soup.find('h1', class_='tm-article-snippet__title tm-article-snippet__title_h1').find('span').text
    return [name, r.status_code]

def main(urls):
    records = [(url, headers) for url in urls]
    with Pool(3) as p:
        name = p.starmap(get_data, records)
    for x in name:
        ws.append(x)
    wb.save('test.xlsx') # Сохранение файла

if __name__ == '__main__':
    main(urls)
→ Ссылка