Форум сайта python.su
0
Привет всем!
Есть код, в котором происходит запрос к Steam API. Запрос - urllib.request.urlopen(url). Запрос занимает около половины секунды, что меня устраивает. Меня не устраивает .read(), который занимает около 2 секунд. Из-за большого кол-ва запроса 2 секунды могут перерасти в минуты. Как можно его ускорить?
Может я не прав, но по-моему единственный шанс ускорить код - использовать потоки. И если я прав как это сделать? Пробовал запускать в двух потоках, одну и ту же функцию(включает в себя вызов других функций), потоки шли друг за другом, а не одновременно.
Офлайн
221
я что то не могу понять о чем речь идет. это какая библиотека urllib, где есть request? Да и лучше сразу бы код показать. А то как то 2 секунды на read() это выглядит странно, если понимать этот метод как и в случае стандартной urllib
Офлайн
0
import urllib.request import time import sqlite3 import json token = '' #Должен быть токен от стима def check_id64(str, name): req = 'http://api.steampowered.com/ISteamUser/GetPlayerSummaries/v0002/?key=%s&steamids=%s' % (token, str) req = urllib.request.urlopen(req).read().decode('utf-8') if name in req: return True else: return False def parse(): # gamers = str(input()) gamers = 'Member[0] id = [U:1:103130828] name = !Butthurtus Maximus'.split('\n') ids = [] nicks = [] for x in range(len(gamers)): id = gamers[x].split(':')[2].split(']')[0] nick = gamers[x].split('=')[2][1:] ids.append(id) nicks.append(nick) return ids, nicks def get_id64(id, nick): key = 76561197960265728 id64s = [] for x in range(len(id)): id64 = int(id[x]) + key result = check_id64(str(id64), nick[x]) if result: id64s.append(id64) else: id64 = id64 + 1 id64s.append(id64) return id64s def get_backpack(id): req = 'http://api.steampowered.com/IEconItems_570/GetPlayerItems/v0001/?key=%s&steamid=%s' % (token, str(id[0])) request = urllib.request.urlopen(req).read() #Тот самый read request = request.decode() json_item = json.loads(request)['result']['items'] player_items = [] for elem in json_item: defindex = elem['defindex'] if defindex not in player_items: player_items.append(defindex) return player_items def find(defind): t = (defind, ) conn = sqlite3.connect('dota2items.db') c = conn.cursor() c.execute('select * from items where defindex=?', t) return c def get_items(sorted_items): items_ready = [] for elem in sorted_items: item = find(str(elem)).fetchone() items_ready.append(item) return items_ready def main(): data = parse() id = data[0] nickname = data[1] id64 = get_id64(id, nickname) items = get_items(get_backpack(id64)) if __name__ == '__main__': a = time.time() main() print(time.time() - a)
Отредактировано snakeand1 (Апрель 10, 2014 14:22:58)
Офлайн
857
JOHN_16это не requests
я что то не могу понять о чем речь идет. это какая библиотека urllib, где есть request?
snakeand1вообще, можно не через .read() читать, а через next()
Меня не устраивает .read(), который занимает около 2 секунд. Из-за большого кол-ва запроса 2 секунды могут перерасти в минуты. Как можно его ускорить?
>>> import urllib.request >>> data = urllib.request.urlopen('http://python.su') >>> next(data) b'\n' >>> next(data) b'\n' >>> next(data) b'\n' >>> next(data) b'\n' >>> next(data) b'\n' >>> next(data) b'<!doctype html>\n' >>> >>> >>> for i, _ in zip(data, range(3)): ... i ... b'<!-- paulirish.com/2008/conditional-stylesheets-vs-css-hacks-answer-neither/ -->\n' b'<!--[if lt IE 7 ]> <html lang="en" class="no-js ie6"> <![endif]-->\n' b'<!--[if IE 7 ]> <html lang="en" class="no-js ie7"> <![endif]-->\n' >>>
snakeand1если запросов много, то лучше распределить их, чтобы они параллельно работали
Может я не прав, но по-моему единственный шанс ускорить код - использовать потоки.
snakeand1непонятно, как ты запускал и как диагностировал
Пробовал запускать в двух потоках, одну и ту же функцию(включает в себя вызов других функций), потоки шли друг за другом, а не одновременно.
Офлайн
0
Запускал я потоки, скорее всего, неправильно
t1 = threading.Thread(target=main, args=(0, )) t2 = threading.Thread(target=main, args=(1, )) t1.start() t2.start() t1.join(); t2.join()
Офлайн
0
Попытался написать потокобезопасный код(заменил все списки на очереди)
def get_id64(id, nick): key = 76561197960265728 for x in range(len(id)): id64 = int(id[x]) + key result = check_id64(str(id64), nick[x]) if result: info = id64, nick[x] gamer_queue.put(info) else: id64 += 1 info = id64, nick[x] gamer_queue.put(info)
Отредактировано snakeand1 (Апрель 12, 2014 10:28:56)
Офлайн
0
Вообщем все сделал - потоки работают, но работают они через одно место.
Код
a = time.time() find_info() thread1 = threading.Thread(target=main) thread2 = threading.Thread(target=main) thread1.start() thread2.start() print(time.time() - a)
http://api.steampowered.com/IEconItems_570/GetPlayerItems/v0001/?key=&steamid=76561198063396556 http://api.steampowered.com/IEconItems_570/GetPlayerItems/v0001/?key=&steamid=76561198075819059 3.1671149730682373 http://api.steampowered.com/IEconItems_570/GetPlayerItems/v0001/?key=&steamid=76561198043509835 http://api.steampowered.com/IEconItems_570/GetPlayerItems/v0001/?key=&steamid=76561198079601121 http://api.steampowered.com/IEconItems_570/GetPlayerItems/v0001/?key=&steamid=76561197980940780 http://api.steampowered.com/IEconItems_570/GetPlayerItems/v0001/?key=&steamid=76561198070399982 Process finished with exit code 0
Отредактировано snakeand1 (Апрель 12, 2014 10:49:49)
Офлайн
0
Все сделал! Чтобы все выполнялось по-порядку, надо было написать thread1.join()
thread2.join().
Тему можно закрывать!
Офлайн