Найти - Пользователи
Полная версия: Нужна помощь с многопоточностью Selenium
Начало » Python для новичков » Нужна помощь с многопоточностью Selenium
1
bs0d
Добрый вечер, коллеги.
Знаю, что не по правилам просить сделать за меня какую-либо работу, без собственных наработок. Нет мне оправдания, в общем.

Но, с Вашего разрешения, я все же попробую….
Имеем такой проект (основная часть кода урезана), использующий селениум вебдрайвер.
Необходимо сделать многопоточное приложение, но… Я еще не сталкивался с многопоточностью, мне тяжело себе даже представить стуктуру кода. Плюс к этому: приложение использует доступ к файлам (как в основном методе start(), так и в цикле: get_acc()). О локах и очередях, я конечно слыхивал, но опять же - не практиковал…

Прошу дать мне не хилый пинок, и наградить каким-нибудь абстрактным скелетом, дальше думаю я сам разберусь, согласно докам (чтение которых иногда вводит меня в жесткий ступор, благо стековер и гугл еще в моем распоряжении)

#imports
 
def is_element_present(driver, how, what):
    try: driver.find_element(by=how, value=what)
    except NoSuchElementException: return False
    return True
 
def load_data(filename):
    with open(filename, 'r') as file:
        data_list = [line.strip() for line in file]
    file.close()
    return data_list
 
def get_mail():
    mails = load_data('mails.txt')
    rand_mail = mails[0]
    mails.remove(rand_mail)
    with open('mails.txt', 'w') as file:
        [file.write('%s\n' % ml) for ml in mails]
    file.close()
    return rand_mail
 
def get_acc():
    accs = load_data('accs.txt')
    acc = accs[0]
    accs.remove(acc)
    with open('accs.txt', 'w') as file:
        [file.write('%s\n' % ml) for ml in accs]
    file.close()
    return acc
 
def save_valid(data):
    with open('valid.txt', 'a') as file:
        file.write('%s\n' % data)
    file.close()
 
def start(prox, login, passw):
    ....
    get_mail()
    ....
 
def check_proxy(proxy):
    import requests, requests.exceptions
    #http://user:pass@10.10.1.10:3128/
    proxies = {"http": proxy}
    try:
        resp = requests.get('http://seemyip.com/', proxies=proxies, timeout=10).text
    except requests.exceptions.RequestException:
        print('can\'t connect to proxy %s' % proxy)
        return False
    return True
 
 
accs = load_data('accs.txt')
proxy = load_data('proxy.txt')
 
for pr in proxy:
    if check_proxy(pr):
        x = get_acc()
        mail, passw = x.split(':')
        start(pr, mail, passw)
bs0d
Видимо ответа так и не дождусь

В общем планирую использовать библиотеку multiprocessing.dummy, класс Pool или Process
Могу сделать например через метод map класса Pool:
pool = Pool(5)
pool.map(start_method, list_of_accs)
Тут имеем 5 потоков, которые применят start_method к списку list_of_accs

Или через Process:
for x in range(5):
    p = Process(target=start_method, args=(llist_of_accs,))
    p.start()
В этом случае будет обработано, неизвестно почему, только 5 элементов списка llist_of_accs. Каким образом мне использовать этот вариант, чтобы был обработан весь список? Вариант с кол-вом потоков == кол-ву элементов списка - не подходит, список может быть и 50 элементов и 5000.

И каким образом (для обоих методов) мне разграничить доступ к list_of_accs, если start получает элемент списка например через такой метод:
def get_acc(llist_of_accs):
    try:
        acc = llist_of_accs[0]
        del llist_of_accs[0]
    except:
        acc = None
    with open('accs.txt', 'w') as file:
        [file.write('%s\n' % ac) for ac in list_of_accs]
        file.close()
    return acc
Пробовал и Lock и RLock, но тестовый код работает одинаково хорошо, хоть с ними хоть без них

З.Ы. почему методы мне удобнее называть функциями? О_О
ajib6ept
import urllib2
from multiprocessing.dummy import Pool as ThreadPool
 
urls = [
    'http://www.python.org',
    'http://www.python.org/about/',
    'http://www.onlamp.com/pub/a/python/2003/04/17/metaclasses.html',
    'http://www.python.org/doc/',
    'http://www.python.org/download/',
    'http://www.python.org/getit/',
    'http://www.python.org/community/',
    'https://wiki.python.org/moin/',
    'http://planet.python.org/',
    'https://wiki.python.org/moin/LocalUserGroups',
    'http://www.python.org/psf/',
    'http://docs.python.org/devguide/',
    'http://www.python.org/community/awards/'
    # etc.. 
    ]
 
# Make the Pool of workers
pool = ThreadPool(4)
 
# Open the urls in their own threads
# and return the results
results = pool.map(urllib2.urlopen, urls)
 
#close the pool and wait for the work to finish 
pool.close()
pool.join()
 
# (c) http://toly.github.io/blog/2014/02/13/parallelism-in-one-line/
bs0d
ajib6ept
Спасибо, я читал эту статью. как минимум - она не раскрывает вопроса: а что если метод внутри себя взаимодействует с другими списками или файлами. Т.е. в принципе я уже понял как это все работает, но хотелось бы сделать правильно, а не абы-как, чтобы не нарваться на кучу последующих граблей.

Допустим я буду использовать этот вариант, как мне правильно установить блокировки в методах, которые будут взаимодействовать с файлами и списками и будут вызываться из основного метода
ajib6ept
Не совсем понял, взяли из файлов исходные данные, закинули в очередь, после завершения сохранили.
Alen
bs0d
Необходимо сделать многопоточное приложение, но…

А цель какая? А то вдруг окажется, что в Jenkins достаточно галочку поставить напротив “Разрешить паралельный запуск тестов” .
bs0d
необходимо быстро обрабатывать списки логин:пароль с помощью вебдрайвера
думаю мне эта галочка не помогла бы, даже если бы я заюзал дженкинс
bs0d
ajib6ept
спасибо, почитаю об очередях
This is a "lo-fi" version of our main content. To view the full version with more information, formatting and images, please click here.
Powered by DjangoBB