Как скачать статистику игроков world of tanks / Павел...
TRANSCRIPT
![Page 1: Как скачать статистику игроков World of Tanks / Павел Пересторонин [Python Meetup 27.03.15]](https://reader034.vdocuments.net/reader034/viewer/2022051400/55a65e761a28ab45798b48bd/html5/thumbnails/1.jpg)
Как скачать статистику игроковWorld of Tanks за одну ночь
Павел Пересторонин
![Page 2: Как скачать статистику игроков World of Tanks / Павел Пересторонин [Python Meetup 27.03.15]](https://reader034.vdocuments.net/reader034/viewer/2022051400/55a65e761a28ab45798b48bd/html5/thumbnails/2.jpg)
История• Игроки
• Танки
• Бои
• Победы
• Поражения
• Статистика
• Процент побед на каждом танке
2
![Page 3: Как скачать статистику игроков World of Tanks / Павел Пересторонин [Python Meetup 27.03.15]](https://reader034.vdocuments.net/reader034/viewer/2022051400/55a65e761a28ab45798b48bd/html5/thumbnails/3.jpg)
49.9%
![Page 4: Как скачать статистику игроков World of Tanks / Павел Пересторонин [Python Meetup 27.03.15]](https://reader034.vdocuments.net/reader034/viewer/2022051400/55a65e761a28ab45798b48bd/html5/thumbnails/4.jpg)
Не все танки одинаково полезны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
![Page 5: Как скачать статистику игроков World of Tanks / Павел Пересторонин [Python Meetup 27.03.15]](https://reader034.vdocuments.net/reader034/viewer/2022051400/55a65e761a28ab45798b48bd/html5/thumbnails/5.jpg)
Нужно больше данных
![Page 6: Как скачать статистику игроков World of Tanks / Павел Пересторонин [Python Meetup 27.03.15]](https://reader034.vdocuments.net/reader034/viewer/2022051400/55a65e761a28ab45798b48bd/html5/thumbnails/6.jpg)
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
![Page 7: Как скачать статистику игроков World of Tanks / Павел Пересторонин [Python Meetup 27.03.15]](https://reader034.vdocuments.net/reader034/viewer/2022051400/55a65e761a28ab45798b48bd/html5/thumbnails/7.jpg)
Нужно с чего-то начать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
![Page 8: Как скачать статистику игроков World of Tanks / Павел Пересторонин [Python Meetup 27.03.15]](https://reader034.vdocuments.net/reader034/viewer/2022051400/55a65e761a28ab45798b48bd/html5/thumbnails/8.jpg)
3+ месяцев
![Page 9: Как скачать статистику игроков World of Tanks / Павел Пересторонин [Python Meetup 27.03.15]](https://reader034.vdocuments.net/reader034/viewer/2022051400/55a65e761a28ab45798b48bd/html5/thumbnails/9.jpg)
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
![Page 10: Как скачать статистику игроков World of Tanks / Павел Пересторонин [Python Meetup 27.03.15]](https://reader034.vdocuments.net/reader034/viewer/2022051400/55a65e761a28ab45798b48bd/html5/thumbnails/10.jpg)
2+ суток
![Page 11: Как скачать статистику игроков World of Tanks / Павел Пересторонин [Python Meetup 27.03.15]](https://reader034.vdocuments.net/reader034/viewer/2022051400/55a65e761a28ab45798b48bd/html5/thumbnails/11.jpg)
concurrent.futures.ThreadPoolExecutor• Сложно отлаживать и останавливать
• Фиксированное число потоков
• …которые все время чего-то ждут
11
![Page 12: Как скачать статистику игроков World of Tanks / Павел Пересторонин [Python Meetup 27.03.15]](https://reader034.vdocuments.net/reader034/viewer/2022051400/55a65e761a28ab45798b48bd/html5/thumbnails/12.jpg)
![Page 13: Как скачать статистику игроков World of Tanks / Павел Пересторонин [Python Meetup 27.03.15]](https://reader034.vdocuments.net/reader034/viewer/2022051400/55a65e761a28ab45798b48bd/html5/thumbnails/13.jpg)
Event Loopimport 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
![Page 14: Как скачать статистику игроков World of Tanks / Павел Пересторонин [Python Meetup 27.03.15]](https://reader034.vdocuments.net/reader034/viewer/2022051400/55a65e761a28ab45798b48bd/html5/thumbnails/14.jpg)
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
![Page 15: Как скачать статистику игроков World of Tanks / Павел Пересторонин [Python Meetup 27.03.15]](https://reader034.vdocuments.net/reader034/viewer/2022051400/55a65e761a28ab45798b48bd/html5/thumbnails/15.jpg)
Keep-Aliveconnector = aiohttp.TCPConnector()
# …
response = yield from aiohttp.request(
'get', 'http://python.org', connector=connector )
01.
02.
03.
04.
15
![Page 16: Как скачать статистику игроков World of Tanks / Павел Пересторонин [Python Meetup 27.03.15]](https://reader034.vdocuments.net/reader034/viewer/2022051400/55a65e761a28ab45798b48bd/html5/thumbnails/16.jpg)
wait_for и sleepasyncio.get_event_loop().run_until_complete(
asyncio.wait_for (
aiohttp.request("GET", "http://ya.ru"),
0.01,
))
01.
02.
03.
04.
05.
16
![Page 17: Как скачать статистику игроков World of Tanks / Павел Пересторонин [Python Meetup 27.03.15]](https://reader034.vdocuments.net/reader034/viewer/2022051400/55a65e761a28ab45798b48bd/html5/thumbnails/17.jpg)
Еще ничего не ускорилиНо у нас уже есть конкурентный однопоточный код, который
поддерживает одновременное ожидание нескольких запросов.
17
![Page 18: Как скачать статистику игроков World of Tanks / Павел Пересторонин [Python Meetup 27.03.15]](https://reader034.vdocuments.net/reader034/viewer/2022051400/55a65e761a28ab45798b48bd/html5/thumbnails/18.jpg)
Нужно больше запросов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
![Page 19: Как скачать статистику игроков World of Tanks / Павел Пересторонин [Python Meetup 27.03.15]](https://reader034.vdocuments.net/reader034/viewer/2022051400/55a65e761a28ab45798b48bd/html5/thumbnails/19.jpg)
Нужно больше запросовТеперь на каждой итерации можно подстраивать число запросов в
очереди.
Например, подсчитывая число ошибок REQUEST_LIMIT_EXCEEDED .
19
![Page 20: Как скачать статистику игроков World of Tanks / Павел Пересторонин [Python Meetup 27.03.15]](https://reader034.vdocuments.net/reader034/viewer/2022051400/55a65e761a28ab45798b48bd/html5/thumbnails/20.jpg)
Зачем это всё?• Хорошо отлаживается
• Не нужно думать про синхронизацию
• Работает быстрее
20
![Page 21: Как скачать статистику игроков World of Tanks / Павел Пересторонин [Python Meetup 27.03.15]](https://reader034.vdocuments.net/reader034/viewer/2022051400/55a65e761a28ab45798b48bd/html5/thumbnails/21.jpg)
Занимательная статистика• 14 часов
• Последний ID на RU-регионе: 40 751 344
• 19 905 151 игроков
• 632 538 123 танков
• 31.8 танков в среднем на аккаунт
• Дамп уместился в 2752.5MiB .
• 145B на аккаунт. 4.6B на танк.
21