Python: Pyppeteer с asyncio - PullRequest
       34

Python: Pyppeteer с asyncio

0 голосов
/ 26 июня 2018

Я проводил несколько тестов, и мне интересно, работает ли приведенный ниже скрипт асинхронно?

# python test.py  It took 1.3439464569091797 seconds.

31 (сайты) x 1,34 = 41,54 с - так что это на несколько секунд меньше, но теоретически это займет всего столько времени, сколько длится самый длинный запрос?

# python test.py  It took 28.129364728927612 seconds.

Возможно, открытие браузера здесь не является асинхронным, и я должен использовать executor для этого?

# cat test.py 
import asyncio
import time

from pyppeteer import launch
from urllib.parse import urlparse

WEBSITE_LIST = [
    'http://envato.com',
    'http://amazon.co.uk',
    'http://amazon.com',
    'http://facebook.com',
    'http://google.com',
    'http://google.fr',
    'http://google.es',
    'http://google.co.uk',
    'http://internet.org',
    'http://gmail.com',
    'http://stackoverflow.com',
    'http://github.com',
    'http://heroku.com',
    'http://djangoproject.com',
    'http://rubyonrails.org',
    'http://basecamp.com',
    'http://trello.com',
    'http://yiiframework.com',
    'http://shopify.com',
    'http://airbnb.com',
    'http://instagram.com',
    'http://snapchat.com',
    'http://youtube.com',
    'http://baidu.com',
    'http://yahoo.com',
    'http://live.com',
    'http://linkedin.com',
    'http://yandex.ru',
    'http://netflix.com',
    'http://wordpress.com',
    'http://bing.com',
]

start = time.time()

async def fetch(url):
    browser = await launch(headless=True, args=['--no-sandbox'])
    page = await browser.newPage()
    await page.goto(f'{url}', {'waitUntil': 'load'})
    await page.screenshot({'path': f'img/{urlparse(url)[1]}.png'})
    await browser.close()

async def run():
    tasks = []

    for url in WEBSITE_LIST:
        task = asyncio.ensure_future(fetch(url))
        tasks.append(task)

    responses = await asyncio.gather(*tasks)
    #print(responses)

#asyncio.get_event_loop().run_until_complete(fetch('http://yahoo.com'))
loop = asyncio.get_event_loop()
future = asyncio.ensure_future(run())
loop.run_until_complete(future)

print(f'It took {time.time()-start} seconds.')

1 Ответ

0 голосов
/ 27 июня 2018

Согласно исходному коду pyppeteer, он использует подпроцесс без каналов для управления процессами Chromium и веб-сокеты для связи, поэтому он асинхронный.

У вас есть 31 сайт, тогда у вас будет 31 + 1 процесс. Поэтому, если у вас нет ЦП с 32 ядрами (возможны также потоки, системные процессы, блокировки, гиперпоточность и все другие факторы, влияющие на результат, так что это просто неточный пример), он не будет полностью выполнен параллельно . Таким образом, узким местом, на мой взгляд, является открытие браузеров процессором, рендеринг веб-страниц и сброс в изображения. Использование executor не поможет.

Однако, это все еще асинхронно. Это означает, что ваш процесс Python не заблокирован, вы все равно можете запустить другой код или дождаться сетевых результатов одновременно . Только когда процессор полностью загружен другими процессами, процессу Python становится труднее «украсть» время процессора.

...