Как скачать статистику игроков
World of Tanks за одну ночь
Павел Пересторонин
История
• Игроки
• Танки
• Бои
• Победы
• Поражения
• Статистика
• Процент побед на каждом танке
2
49.9%
Не все танки одинаково полезны
Pz.Kpfw. 38 (t) n.A. 57%
БТ-2 55%
Type 3 Chi-Nu 47%
Type 1 Chi-He 46%
Type 4 Chi-To 33%
4
Нужно больше данных
https://api.worldoftanks.ru/wot/account/tanks/
…, {
"statistics": {
"wins": 21 ,
"battles": 51
},
"mark_of_mastery": 1,
"tank_id": 1025
}, …
01.
02.
03.
04.
05.
06.
07.
08.
6
Нужно с чего-то начать
for account_id in range(1, 50000000):
requests.get(
"https://api.worldoftanks.ru/wot/account/tanks/",
params={
"account_id": account_id,
"application_id": "…",
},
)
01.
02.
03.
04.
05.
06.
07.
08.
7
3+ месяцев
Keep-Alive
$ python -m timeit -s "import requests" -- 
"requests.get('http://google.com')"
10 loops, best of 3: 543 msec per loop
$ python -m timeit -s 
"import requests; s = requests.Session() " -- 
"s.get('http://google.com')"
10 loops, best of 3: 313 msec per loop
01.
02.
03.
01.
02.
03.
04.
9
2+ суток
concurrent.futures.ThreadPoolExecutor
• Сложно отлаживать и останавливать
• Фиксированное число потоков
• …которые все время чего-то ждут
11
Как скачать статистику игроков World of Tanks / Павел Пересторонин [Python Meetup 27.03.15]
Event Loop
import asyncio, aiohttp
@asyncio.coroutine
def func():
response = yield from aiohttp.request(
"GET", "http://ya.ru")
text = yield from response.text()
print(text)
asyncio.get_event_loop().run_until_complete(func())
01.
02.
03.
04.
05.
06.
07.
08.
13
response = yield from aiohttp.request (
"GET",
"http://api.worldoftanks.ru/wot/account/tanks/",
params=params,
)
if response.status == http.client.OK:
json = yield from response.json()
if json["status"] == "ok":
return json["data"]
logging.warning("API error: %s", json["error"]["message"])
01.
02.
03.
04.
05.
06.
07.
08.
09.
10.
14
Keep-Alive
connector = aiohttp.TCPConnector()
# …
response = yield from aiohttp.request(
'get', 'http://python.org', connector=connector )
01.
02.
03.
04.
15
wait_for и sleep
asyncio.get_event_loop().run_until_complete(
asyncio.wait_for (
aiohttp.request("GET", "http://ya.ru"),
0.01,
))
01.
02.
03.
04.
05.
16
Еще ничего не ускорили
Но у нас уже есть конкурентный однопоточный код, который
поддерживает одновременное ожидание нескольких запросов.
17
Нужно больше запросов
pending = set()
for account_ids in chop(range(start_id, end_id + 1), 100):
pending.add(asyncio.async(api.account_tanks(account_ids)))
if len(pending) < max_pending_count :
continue
done, pending = yield from asyncio.wait (
pending, return_when= asyncio.FIRST_COMPLETED)
# TODO: done.result()
01.
02.
03.
04.
05.
06.
07.
08.
18
Нужно больше запросов
Теперь на каждой итерации можно подстраивать число запросов в
очереди.
Например, подсчитывая число ошибок REQUEST_LIMIT_EXCEEDED .
19
Зачем это всё?
• Хорошо отлаживается
• Не нужно думать про синхронизацию
• Работает быстрее
20
Занимательная статистика
• 14 часов
• Последний ID на RU-регионе: 40 751 344
• 19 905 151 игроков
• 632 538 123 танков
• 31.8 танков в среднем на аккаунт
• Дамп уместился в 2752.5MiB .
• 145B на аккаунт. 4.6B на танк.
21
sys.exit()
• eigenein@gmail.com
• https://medium.com/@eigenein
• https://telegram.me/eigenein
22

More Related Content

PPTX
Wargaming: тыл - фронту!
PDF
Архитектура поиска в Avito / Андрей Смирнов (Avito)
PDF
"Пиринговый веб на JavaScript"
PPTX
СУБД осень 2012 вестник 5
PPTX
Продвинутая web-отладка с Fiddler
PDF
Обзор фреймворка Twisted
PPTX
SWIG — cоздание мультиязыковых интерфейсов для C/C++ библиотек
PDF
Practical Python Packaging / Стас Рудаков / Web Developer Wargaming
Wargaming: тыл - фронту!
Архитектура поиска в Avito / Андрей Смирнов (Avito)
"Пиринговый веб на JavaScript"
СУБД осень 2012 вестник 5
Продвинутая web-отладка с Fiddler
Обзор фреймворка Twisted
SWIG — cоздание мультиязыковых интерфейсов для C/C++ библиотек
Practical Python Packaging / Стас Рудаков / Web Developer Wargaming

Viewers also liked (14)

PDF
Python&Printer / Андрей Пучко / penta.by
PDF
Язык программирования GO
PDF
Очередной скучный доклад про логгирование
PPT
Быстрые конструкции в Python - Олег Шидловский, Python Meetup 26.09.2014
PPTX
Machine learning with Python / Олег Шидловский / Doist [Python Meetup 27.03.15]
PDF
PDF
Почему я пишу хороший код, но его никто не ценит, кроме моей мамы / Павел Меш...
PPTX
Максим Щепелин. "Unittesting. Как?"
PPTX
Обзор способов написания конкурентных программ в питоне
PDF
Про асинхронность / Максим Щепелин / Web Developer Wargaming
PDF
Redis. Как мы боролись со сложностью
PPTX
OpenSource CMS и ERP система в одном флаконе / Олег Курьян / технический дире...
PPTX
S.O.L.I.D. - Павел Кохан, Python Meetup 26.09.2014
PPTX
Python AST / Николай Карелин / VPI Development Center [Python Meetup 27.03.15]
Python&Printer / Андрей Пучко / penta.by
Язык программирования GO
Очередной скучный доклад про логгирование
Быстрые конструкции в Python - Олег Шидловский, Python Meetup 26.09.2014
Machine learning with Python / Олег Шидловский / Doist [Python Meetup 27.03.15]
Почему я пишу хороший код, но его никто не ценит, кроме моей мамы / Павел Меш...
Максим Щепелин. "Unittesting. Как?"
Обзор способов написания конкурентных программ в питоне
Про асинхронность / Максим Щепелин / Web Developer Wargaming
Redis. Как мы боролись со сложностью
OpenSource CMS и ERP система в одном флаконе / Олег Курьян / технический дире...
S.O.L.I.D. - Павел Кохан, Python Meetup 26.09.2014
Python AST / Николай Карелин / VPI Development Center [Python Meetup 27.03.15]
Ad

More from Python Meetup (12)

PDF
Python для анализа данных
PDF
Асинхронное распределенное выполнение задач. Stdlib, Celery, RQ и собственные...
PDF
Использование gevent для эмуляции высокой нагрузки
PDF
Введение в GIL и новый GIL
PDF
Недостатки Python
PDF
Социальный игровой сервер на Python: от первого коммита до продакшена
PDF
Портируем на Python 3
PDF
Garbage collector and a bit of memory management
PPTX
Неочевидное поведение некоторых конструкций
PDF
Pyton – пробуем функциональный стиль
PDF
Dictionary в Python. По мотивам Objects/dictnotes.txt
PDF
"Внутренности" CPython, часть II
Python для анализа данных
Асинхронное распределенное выполнение задач. Stdlib, Celery, RQ и собственные...
Использование gevent для эмуляции высокой нагрузки
Введение в GIL и новый GIL
Недостатки Python
Социальный игровой сервер на Python: от первого коммита до продакшена
Портируем на Python 3
Garbage collector and a bit of memory management
Неочевидное поведение некоторых конструкций
Pyton – пробуем функциональный стиль
Dictionary в Python. По мотивам Objects/dictnotes.txt
"Внутренности" CPython, часть II
Ad

Как скачать статистику игроков World of Tanks / Павел Пересторонин [Python Meetup 27.03.15]