Найти - Пользователи
Полная версия: Асинхронные web запросы
Начало » Python для новичков » Асинхронные web запросы
1 2
Alen
wegwgweg
Можете пояснить пожалуйста, что тут реализовано http://habrahabr.ru/post/243207/? На сколько я понимаю там показано как вручную реализовать асинхронное выполнение кода. Или я ошибаюсь?

Вручную вы можете организовать асинхронный код как угодно. Для этого вам достаточно написать общий цикл и «всего лишь» придумать механизм получения и обработки событий. В жизни для этого есть готовые библиотеки, в которых за вас уже подумали, и на грабли за вас уже понаступали, и даже PEP написали и в стандартную библиотеку включили. Еще есть сверхлегкий магический способ для ленивых — как превратить любое приложение в асинхронное с помощью манки-патча из библиотеки gevent.

Но лучший способ все понять — реализовать, опираясь на документацию, пару-тройку простых асинхронных приложений, в строк 20-50 каждое. Нюансы можно отлавливать на более солидных приложениях, если вам это действительно нужно.
alex925
Мне понравилась эта статья http://compiletoi.net/fast-scraping-in-python-with-asyncio.html, попробуй почитать.
plusplus
По корутинам я бы посоветовал вот эту мега презентацию http://www.dabeaz.com/coroutines/coroutines.zip
Рассказывается про корутины и где они могут пригодится, в том числе и для асинхронности.
4kpt_III
plusplus
Поддержу. Презентация просто шикарная.
wegwgweg
Читал статью http://compiletoi.net/fast-scraping-in-python-with-asyncio.html и возникла небольшая проблема с пониманием и перевод предложения
aiohttp.request is a coroutine, and so is the read method, so we'll need to use yield from to call them.
Я перевёл это примерно так:
aiohttp.request это сопрограмма и по этому при чтении ответа сервера методом read, мы должны использовать yield from.
Правильно я перевёл?
GreyZmeem
wegwgweg
Правильно я перевёл?
aiohttp.request является coroutine, также как и метод read, потом для ним мы должны использовать yield from
wegwgweg
GreyZmeem
Вы приводили пример кода:
import asyncio
import aiohttp
 
 
@asyncio.coroutine
def get(method, url, **kwargs):
    response = yield from aiohttp.request(method, url, **kwargs)
    body = yield from response.read()
    return body
 
 
@asyncio.coroutine
def main():
    tasks = [
        asyncio.async(get('GET', 'http://python.org')),
        asyncio.async(get('GET', 'http://python.su')),
        asyncio.async(get('GET', 'http://python.net')),
    ]
    done, pending = yield from asyncio.wait(tasks)
    for item in done:
        print(item.result())
 
 
if __name__ == '__main__':
    loop = asyncio.get_event_loop()
    loop.run_until_complete(main())

Я хотел бы уточнить у вас. Я хочу получить скачанные страницы для дальнейшего парсинга, мне нужно в функции main добавлять результат в какой-нибудь внешний список и потом уже после завершения этого кода проводить их обработку или как мне действовать?
GreyZmeem
done, pending = yield from asyncio.wait(tasks)
    for item in done:
        print(item.result())
asyncio.wait возвращает два сета: done и penging. В них содержаться Future ваших заданий. Соответственно вы можете передать done в какой-то метод для дальнейшей обработки.

Если вы не хотите ждать пока завершаться все задания, то можно создавать каждое задание отдельно и добавить callback по завершению.
import asyncio
import aiohttp
import functools
 
 
@asyncio.coroutine
def get(method, url, **kwargs):
    response = yield from aiohttp.request(method, url, **kwargs)
    body = yield from response.read()
    return body
 
 
def done_callback(task, future):
    print('Done {}: {}'.format(task, future))
  
  
@asyncio.coroutine
def main():
    tasks = [
        ('GET', 'http://python.org'),
        ('GET', 'http://python.su'),
        ('GET', 'http://python.net'),
    ]
    futures = []
    for task in tasks:
        print('Creating task: {}'.format(task))
        future = asyncio.async(get(*task))
        future.add_done_callback(functools.partial(done_callback, task))
        futures.append(future)
    yield from asyncio.wait(futures)
 
 
if __name__ == '__main__':
    loop = asyncio.get_event_loop()
    loop.run_until_complete(main())
This is a "lo-fi" version of our main content. To view the full version with more information, formatting and images, please click here.
Powered by DjangoBB