Как скачать статистику игроков world of tanks / Павел...

22
Как скачать статистику игроков World of Tanks за одну ночь Павел Пересторонин

Upload: python-meetup

Post on 15-Jul-2015

434 views

Category:

Software


0 download

TRANSCRIPT

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

Как скачать статистику игроковWorld of Tanks за одну ночь

Павел Пересторонин

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

История• Игроки

• Танки

• Бои

• Победы

• Поражения

• Статистика

• Процент побед на каждом танке

2

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

49.9%

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

Не все танки одинаково полезны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]

Нужно больше данных

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

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]

Нужно с чего-то начать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]

3+ месяцев

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

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]

2+ суток

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

concurrent.futures.ThreadPoolExecutor• Сложно отлаживать и останавливать

• Фиксированное число потоков

• …которые все время чего-то ждут

11

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

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]

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]

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]

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]

Еще ничего не ускорилиНо у нас уже есть конкурентный однопоточный код, который

поддерживает одновременное ожидание нескольких запросов.

17

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

Нужно больше запросов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]

Нужно больше запросовТеперь на каждой итерации можно подстраивать число запросов в

очереди.

Например, подсчитывая число ошибок REQUEST_LIMIT_EXCEEDED .

19

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

Зачем это всё?• Хорошо отлаживается

• Не нужно думать про синхронизацию

• Работает быстрее

20

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

Занимательная статистика• 14 часов

• Последний ID на RU-регионе: 40 751 344

• 19 905 151 игроков

• 632 538 123 танков

• 31.8 танков в среднем на аккаунт

• Дамп уместился в 2752.5MiB .

• 145B на аккаунт. 4.6B на танк.

21

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

sys.exit()• [email protected]

• https://medium.com/@eigenein

• https://telegram.me/eigenein

22