Уведомления

Группа в Telegram: @pythonsu

#1 Фев. 11, 2015 23:19:04

Alen
Зарегистрирован: 2013-08-01
Сообщения: 373
Репутация: +  49  -
Профиль   Отправить e-mail  

Асинхронные web запросы

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

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

Но лучший способ все понять — реализовать, опираясь на документацию, пару-тройку простых асинхронных приложений, в строк 20-50 каждое. Нюансы можно отлавливать на более солидных приложениях, если вам это действительно нужно.

Офлайн

#2 Фев. 11, 2015 23:20:45

alex925
Зарегистрирован: 2015-01-08
Сообщения: 204
Репутация: +  14  -
Профиль   Отправить e-mail  

Асинхронные web запросы

Мне понравилась эта статья http://compiletoi.net/fast-scraping-in-python-with-asyncio.html, попробуй почитать.

Офлайн

#3 Фев. 12, 2015 09:09:19

plusplus
От:
Зарегистрирован: 2009-01-05
Сообщения: 418
Репутация: +  15  -
Профиль   Отправить e-mail  

Асинхронные web запросы

По корутинам я бы посоветовал вот эту мега презентацию http://www.dabeaz.com/coroutines/coroutines.zip
Рассказывается про корутины и где они могут пригодится, в том числе и для асинхронности.



Офлайн

#4 Фев. 12, 2015 10:00:25

4kpt_III
Зарегистрирован: 2014-12-22
Сообщения: 999
Репутация: +  39  -
Профиль   Отправить e-mail  

Асинхронные web запросы

plusplus
Поддержу. Презентация просто шикарная.

Офлайн

#5 Фев. 12, 2015 15:55:32

wegwgweg
Зарегистрирован: 2015-02-02
Сообщения: 12
Репутация: +  0  -
Профиль   Отправить e-mail  

Асинхронные web запросы

Читал статью 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.
Правильно я перевёл?

Офлайн

#6 Фев. 13, 2015 02:30:16

GreyZmeem
От: Киев
Зарегистрирован: 2013-12-03
Сообщения: 147
Репутация: +  34  -
Профиль   Отправить e-mail  

Асинхронные web запросы

wegwgweg
Правильно я перевёл?
aiohttp.request является coroutine, также как и метод read, потом для ним мы должны использовать yield from

Офлайн

#7 Фев. 14, 2015 01:41:55

wegwgweg
Зарегистрирован: 2015-02-02
Сообщения: 12
Репутация: +  0  -
Профиль   Отправить e-mail  

Асинхронные web запросы

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 добавлять результат в какой-нибудь внешний список и потом уже после завершения этого кода проводить их обработку или как мне действовать?

Офлайн

#8 Фев. 16, 2015 02:11:19

GreyZmeem
От: Киев
Зарегистрирован: 2013-12-03
Сообщения: 147
Репутация: +  34  -
Профиль   Отправить e-mail  

Асинхронные web запросы

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())

Офлайн

Board footer

Модераторировать

Powered by DjangoBB

Lo-Fi Version