Скрипт без головы после нескольких запусков

У меня есть скрипт, использующий безголовый браузер, который я использую crontab -e, Он работает нормально первые несколько раз, а затем вылетает со следующей трассировкой:

Traceback (most recent call last):
  File "/home/clint-selenium-firefox.py", line 83, in <module>
    driver.get(url)
  File "/usr/local/lib/python2.7/dist-packages/selenium/webdriver/remote/webdriver.py", line 248, in get
    self.execute(Command.GET, {'url': url})
  File "/usr/local/lib/python2.7/dist-packages/selenium/webdriver/remote/webdriver.py", line 236, in execute
    self.error_handler.check_response(response)
  File "/usr/local/lib/python2.7/dist-packages/selenium/webdriver/remote/errorhandler.py", line 192, in check_response
    raise exception_class(message, screen, stacktrace)
selenium.common.exceptions.WebDriverException: Message: Failed to decode response from marionette

Моя строка crontab:

*/10 * * * * export DISPLAY=:0 && python /home/clint-selenium-firefox.py >> /home/error.log 2>&1

Я не хочу перегружать это скриптом Python, поэтому я вытащил то, что я считаю релевантными.

from pyvirtualdisplay import Display

display = Display(visible=0, size=(800, 600))
display.start()
...
driver = webdriver.Firefox()
driver.get(url)
...
driver.quit()
...
display.stop()

Ваша помощь очень ценится.

РЕДАКТИРОВАТЬ

Версии: Firefox 49.0.2; Селен: 3,0,1; geckodriver: geckodriver-v0.11.1-linux64.tar.gz

Код вокруг ошибки (сбой на driver.get(url)):

driver = webdriver.Firefox()
if DEBUG: print "Opened Firefox"

for u in urls:
    list_of_rows = []
    list_of_old_rows = []

    # get the old version of the site data
    mycsvfile = u[1]
    try:
        with open(mycsvfile, 'r') as csvfile:
            old_data = csv.reader(csvfile, delimiter=' ', quotechar='|')
            for o in old_data:
                list_of_old_rows.append(o)
    except: pass

    # get the new data
    url = u[0]
    if DEBUG: print url    

    driver.get(url)
    if DEBUG: print driver.title
    time.sleep(1)
    page_source = driver.page_source
    soup = bs4.BeautifulSoup(page_source,'html.parser')  

1 ответ

Решение

Из- за сбоя нескольких экземпляров Firefox с NS_ERROR_SOCKET_ADDRESS_IN_USE #99 Это происходит потому, что опция --marionette-port не передается в geckodriver - что означает, что все экземпляры geckodriver запускают firefox через один и тот же требуемый порт по умолчанию (2828). Первый экземпляр firefox связывается с этим портом, будущие экземпляры не могут, и все экземпляры geckodriver заканчивают тем, что соединялись с первым экземпляром firefox - который производит все виды непредсказуемого поведения.

Вслед за этим: я думаю, что разумное краткосрочное решение состоит в том, чтобы сделать то, что делают другие водители, и попросить Марионетт привязать к случайному, свободному порту, сгенерированному geckodriver. В настоящее время он использует 2828 по умолчанию для всех экземпляров Firefox. Поскольку, к сожалению, у Marionette еще нет внеполосного способа сообщить порт обратно клиенту (geckodriver), это по своей природе очень странно, но мы можем улучшить ситуацию в будущем с помощью одного из предложений из ошибки 1240830.

Это изменение было сделано в

Selenium 3.0.0.b2
* Updated Marionette port argument to match other drivers.

Я думаю, случайный работает только так долго. Поднимите проблему. Исправление кода может потребоваться для версий селен, Firefox и Geckodriver, которые у вас есть. Вы можете вернуться к использованию Selenium 2.53.0 и Firefox ESR 38.8, пока это не будет исправлено. Ваш звонок.

ОБНОВЛЕНИЕ: попробуйте

from selenium import webdriver
from selenium.webdriver.firefox.firefox_binary import FirefoxBinary

binary = FirefoxBinary('path/to/binary')
driver = webdriver.Firefox(firefox_binary=binary)
Другие вопросы по тегам