Любой возможный способ ускорить обработку этого?

Сейчас у меня есть список из 80 имен пользователей, и мой скрипт проверяет, существует ли каждое имя пользователя или нет. Однако это занимает немного больше времени, чем мне нравится, поэтому мне было интересно, могу ли я что-нибудь сделать, чтобы ускорить проверку того, существует ли каждое имя пользователя или нет.

# ------------------------------
# Mass Kik Username Checker
# Script Made by: Ski
# ------------------------------

import requests, threading

def check(username):
    try:
        req = requests.get("http://kik.me/"+username, allow_redirects=False).status_code

        if req == 302:
            return False
        if req == 200:
            return True
    except Exception as e:
        print e
        exit()


def _loadList(filename):
    item_list = []
    for item in str(open(filename, "r").read()).split("\n"):
        item_list.append(item)
    return item_list

def _thread(items):
    global _usernames
    for username in _usernames[items[0]:items[1]]:
        exists = check(username)

        if exists:
            print username+" exists\n"
        if not exists:
            print username+" doesn't exist\n"

if __name__ == '__main__':
    _usernames = _loadList("usernames.txt")

    thread1 = threading.Thread(target=_thread, args=([0, 20], )).start()
    thread2 = threading.Thread(target=_thread, args=([20, 40], )).start()
    thread3 = threading.Thread(target=_thread, args=([40, 60], )).start()
    thread4 = threading.Thread(target=_thread, args=([60, 80], )).start()

person vKi    schedule 18.10.2015    source источник
comment
используйте профилирование, чтобы определить узкое место   -  person Moritz    schedule 18.10.2015
comment
Мориц делает хорошее предложение, но если оно не совсем ясно, он имеет в виду стандартные библиотечные модули profile и cProfile. cProfile предпочтительнее.   -  person X-Mann    schedule 18.10.2015
comment
Создайте пул из более чем 4 рабочих потоков, почему бы не 80 или более. И используйте очереди для связи с потоками, а не с глобальными переменными (это не для производительности, а для корректности кода).   -  person uselpa    schedule 18.10.2015
comment
Используйте сеансы. Это даст вам постоянные HTTP-соединения и, следовательно, значительно ускорит запросы к тому же хосту. Это должно быть первым, что вы должны сделать, даже не думая о многопоточности.   -  person Lukas Graf    schedule 18.10.2015


Ответы (1)


Попробуйте Python 3.x Пул потоков . Вы можете определить, сколько рабочих будет выполнять запрос. Использование большего количества (например, 32), чем 4, значительно ускорит ваш код.

import requests
from concurrent.futures import ThreadPoolExecutor


NUM_OF_WORKERS=32


def check(username):
    try:
        req = requests.get("http://kik.me/"+username, allow_redirects=False).status_code

        if req == 302:
            print(username, " does not exist.")
        if req == 200:
            print(username, "exists.")
    except Exception as error:
        print(error)


usernames = _loadList(filename)

with ThreadPoolExecutor(max_workers=NUM_OF_WORKERS) as pool:
    pool.map(check, usernames)

Это также делает ваш код гораздо более читабельным.

РЕДАКТИРОВАТЬ: теперь заметил тег Python 2.7.

Python 2 имеет пул потоков, который доступен в модуле multiprocessing. К сожалению, это не задокументировано, так как тесты не были доступны.

import requests
from multiprocessing.pool import ThreadPool


NUM_OF_WORKERS=32


def check(username):
    try:
       req = requests.get("http://kik.me/"+username, allow_redirects=False).status_code

       if req == 302:
           print(username, " does not exist.")
       if req == 200:
           print(username, "exists.")
    except Exception as error:
        print(error)


usernames = _loadList(filename)


pool = ThreadPool(processes=NUM_OF_WORKERS)
pool.map_async(check, usernames)
pool.close()
pool.join()

Если вам нужен лучший пул потоков для Python 2, попробуйте модуль Pebble.

person noxdafox    schedule 18.10.2015
comment
LOL, я протестировал скрипт с несколькими совершенно случайными именами пользователей и получил несколько существующих. Барнауи например xD - person noxdafox; 18.10.2015
comment
Вопрос помечен python2.7 - person Padraic Cunningham; 18.10.2015