LINUX.ORG.RU

selenium, python, и много-много браузеров мультипоточно

 , ,


1

1

Доброй ночи, Лоровцы. Пайтон знаю не очень хорошо, и недавно столкнулся с одной проблемой. В общем, есть следующий код:

#!/usr/bin/env python2.7
from multiprocessing import Pool
from termcolor import colored
from selenium import webdriver
#from pyvirtualdisplay import Display
from selenium.webdriver.common.desired_capabilities import DesiredCapabilities
import random
import time

urls = ['http://linux.org.ru', 'http://opennet.ru'] # и куча остальных url

def bobo(url):
        bro = webdriver.Remote(
           command_executor='http://192.168.1.125:4444/wd/hub',
           desired_capabilities=DesiredCapabilities.FIREFOX)

        print colored('>>> Start browser', 'green')
        bro.get(url)
        print colored('>>> Get page: ', 'yellow')+colored(url, 'cyan')
        bro.save_screenshot('./screens/'+str(random.random())+'.png')
        print colored('>>> Make screenshot', 'magenta')
        bro.quit()
        print colored('>>> Exit ...', 'red')


if __name__ == '__main__':
    pool = Pool(processes=100)           
    result = pool.map_async(bobo, urls)   
    result.wait()
    print result
    print result.get(timeout=1)          
    print colored('*** END ***', 'red')

На другом компьютере запущен selenium-server, к которому из этого кода я и подключаюсь. Так вот, проблема в том, что через некоторое время начинается какая-то непонятная феерия, которая, выглядит, например, так:

<multiprocessing.pool.MapResult object at 0x7f957bf35390>
Traceback (most recent call last):
  File "./poo.py", line 51, in <module>
    print result.get(timeout=1)          
  File "/usr/lib/python2.7/multiprocessing/pool.py", line 558, in get
    raise self._value
selenium.common.exceptions.WebDriverException: Message: Could not convert screenshot to base64 - Error: Invalid base64 data: data:,
Driver info: driver.version: unknown
Stacktrace:
    at <anonymous class>.FirefoxDriver.prototype.screenshot (file:///tmp/anonymous8234494257891062854webdriver-profile/extensions/fxdriver@googlecode.com/components/drive
r-component.js:9844:5)
    at <anonymous class>.DelayedCommand.prototype.executeInternal_/h (file:///tmp/anonymous8234494257891062854webdriver-profile/extensions/fxdriver@googlecode.com/compone
nts/command-processor.js:11635:16)
    at <anonymous class>.DelayedCommand.prototype.executeInternal_ (file:///tmp/anonymous8234494257891062854webdriver-profile/extensions/fxdriver@googlecode.com/component
s/command-processor.js:11640:7)
    at <anonymous class>.DelayedCommand.prototype.execute/< (file:///tmp/anonymous8234494257891062854webdriver-profile/extensions/fxdriver@googlecode.com/components/comma
nd-processor.js:11582:5)

Ну, и ещё бывают всякие разные ошибки. Например, когда я из этого же кода пытаюсь вызвать phantomjs много раз, без selenium remote, то например, эта программа вываливается со следующими ошибками:

>>> Start browser
<multiprocessing.pool.MapResult object at 0x7f4d9d36ed90>
Traceback (most recent call last):
  File "./poo.py", line 51, in <module>
    print result.get(timeout=1)
  File "/usr/lib/python2.7/multiprocessing/pool.py", line 558, in get
    raise self._value
selenium.common.exceptions.WebDriverException: Message: Can not connect to GhostDriver

Собственно, хочу спросить, как правильно можно использовать толпу браузеров совместно с python? Или я допустил в коде какую-то ошибку? Буду очень признателен за помощь.

Ответ на: комментарий от Ubuntu1210

Я не прошу сделать что-то для меня, я прошу подсказать. :)

gIiIjony
() автор топика

По своему опыту: мы пришли к тому что на одну виртуалку - один запущенный браузер. Какие там были проблеммы сейчас точно не вспомню.

Тоесть один сервак с запущеным гридом и примерно 20 виртуалок, на каждой нод который запускает либо ФФ, либо Хром. Не уверен что это самая оптимальная конфигурация, но работает более-менее стабильно.

По коду: что такое и как работает pool - я хз. Но цифра 100 пугает. Если оно сразу запускает 100 питон процессов это многовато и ненужно. Посмотри на грид http://host:port/grid/console - там может быть много «ожидающих» запросов.

shy
()
Ответ на: комментарий от shy

Хм, интересно. Можно попробовать конечно, но такую адскую хрень придётся городить. :)

Посмотрю, большое спасибо. :)

gIiIjony
() автор топика

как правильно можно использовать толпу браузеров совместно с python?

так это нужно грид (кластер) делать

Lordwind ★★★★★
()

Пальцем небо: твой сервер не успевает обрабатывать запросы всех процессов. Опять же пальцем в небо по поводу того, что можно сделать: увеличить таймаут ожидания ответа сервера, увеличить на сервере пул открытых соединений. Но эти варианты я бы использовал только как временные подпорки для нащупывания проблемы.Правильный вариант - очередь.

anonymous
()
Ответ на: комментарий от anonymous

А, ну и в треде уже сказали о каком-то кластере. Видимо, это и есть самый вариант, раз сам инструмент позволяет решить такие проблемы.

anonymous
()
Ответ на: комментарий от gIiIjony

А в качестве виртуалок что использовали?

Fedora + XFCE

shy
()
Ответ на: комментарий от Lordwind

Я так и делаю. То что я описал - пример на Гриде.

gIiIjony
() автор топика
Ответ на: комментарий от anonymous

Ну, я примерно об этом и думал. Ладно, спасибо, попробую некоторые задержки воткнуть.

gIiIjony
() автор топика
Ответ на: комментарий от anonymous

Дело в том, что я и использую кластер. Возможно как-то неправильно, конечно. Судя по всему, проблема в локах каких-то определённых портов, а исходя из того что я запускаю несколько нод на одном компьютере - то наверняка проблема в этом. Хотя, конечно, не особо уверен. Возможно это как-то всё-таки решается.

gIiIjony
() автор топика
Ответ на: комментарий от gIiIjony

Я, честно говоря, не работал с сабжевыми инструментами, ванговал по тексту ошибки и своему опыту, поэтому и написал, что пальцем в небо.

anonymous
()

Вроде-бы разобрался, дико костыльно конечно. Написал небольшой скрипт, который создаёт несколько десятков lxc-контейнеров, добавляет в бридж, потом чрутится туда, устанавливает java, и всё прочее, качает ноду селениума, создаёт скрипт автозапуска, и потом запускает всё это, и регистрирует ноды в хабе. Вроде работает пока что, и ничего не упало. Пока гоняю две ноды на разных виртуалках в 15 потоков, посмотрим что будет с 50 виртуалками и 100 потоками. Ещё думаю, что lxc для такого избыточно. Может заодно подскажете по другой теме? Слышал о docker, слышал что много штук с ним можно делать. Я могу, допустим, запихать в образ джаву, ноду селениума, браузер, xfvb, и всякие библиотеки для всего этого, и чтобы это было доступно по-сети?

gIiIjony
() автор топика
Ответ на: комментарий от gIiIjony

И по 2 через какое-то время умирает. Пробую по одному. Потом, видимо, придётся пробовать по 0.

gIiIjony
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.