Установка таймаута на веб-драйвере селена.PhantomJS
Ситуация
У меня есть простой скрипт на Python, чтобы получить исходный код HTML для данного URL:
browser = webdriver.PhantomJS()
browser.get(url)
content = browser.page_source
Иногда URL-адрес указывает на страницу с медленно загружаемыми внешними ресурсами (например, видеофайлами или очень медленным рекламным контентом).
Webdriver будет ждать, пока эти ресурсы будут загружены, прежде чем завершить .get(url)
запрос.
Примечание: по посторонним причинам мне нужно делать это с PhantomJS, а не с requests
или же urllib2
Вопрос
Я хотел бы установить тайм-аут на загрузку ресурса PhantomJS, чтобы, если ресурс загружался слишком долго, браузер просто предполагал, что он не существует или что-то еще.
Это позволило бы мне выполнить последующее .pagesource
запрос на основе того, что загружен браузером.
Документация на webdriver.PhantomJS очень тонкая, и я не нашел аналогичного вопроса по SO.
заранее спасибо!
2 ответа
PhantomJS предоставил resourceTimeout
, который может удовлетворить ваши потребности. Я цитирую из документации здесь
(в миллисекундах) определяет время ожидания, после которого любой запрашиваемый ресурс прекратит попытки и перейдет к другим частям страницы. Обратный вызов onResourceTimeout будет вызываться по таймауту.
Так что в Ruby вы можете сделать что-то вроде
require 'selenium-webdriver'
capabilities = Selenium::WebDriver::Remote::Capabilities.phantomjs("phantomjs.page.settings.resourceTimeout" => "5000")
driver = Selenium::WebDriver.for :phantomjs, :desired_capabilities => capabilities
Я верю в Python, это что-то вроде (не проверено, только обеспечивает логику, вы разработчик Python, надеюсь, вы поймете)
driver = webdriver.PhantomJS(desired_capabilities={'phantomjs.page.settings.resourceTimeout': '5000'})
Длинное объяснение ниже, поэтому TLDR:
Текущая версия Ghostdriver от Selenium (в PhantomJS 1.9.8) игнорирует параметр resourceTimeout, использует implicitly_wait(), set_page_load_timeout() веб-драйвера и заключает их в блок try-exc.
#Python
from selenium import webdriver
from selenium.common.exceptions import TimeoutException
browser = webdriver.PhantomJS()
browser.implicitly_wait(3)
browser.set_page_load_timeout(3)
try:
browser.get("http://url_here")
except TimeoutException as e:
#Handle your exception here
print(e)
finally:
browser.quit()
объяснение
Чтобы предоставить параметры страницы PhantomJS для Selenium, можно использовать DesiredCapabilities веб-драйвера, такие как:
#Python
from selenium import webdriver
cap = webdriver.DesiredCapabilities.PHANTOMJS
cap["phantomjs.page.settings.resourceTimeout"] = 1000
cap["phantomjs.page.settings.loadImages"] = False
cap["phantomjs.page.settings.userAgent"] = "faking it"
browser = webdriver.PhantomJS(desired_capabilities=cap)
//Java
DesiredCapabilities capabilities = DesiredCapabilities.phantomjs();
capabilities.setCapability("phantomjs.page.settings.resourceTimeout", 1000);
capabilities.setCapability("phantomjs.page.settings.loadImages", false);
capabilities.setCapability("phantomjs.page.settings.userAgent", "faking it");
WebDriver webdriver = new PhantomJSDriver(capabilities);
Но здесь есть одна загвоздка: как и сегодня (2014/Dec/11) с PhantomJS 1.9.8 и его встроенным Ghostdriver, resourceTimeout не будет применяться Ghostdriver ( см. Выпуск № 380 Ghostdriver в Github).
Чтобы обойти это, просто используйте функции / методы тайм-аута Selenium и оберните метод get веб-драйвера в блок try-исключением / try-catch, например:
#Python
from selenium import webdriver
from selenium.common.exceptions import TimeoutException
browser = webdriver.PhantomJS()
browser.implicitly_wait(3)
browser.set_page_load_timeout(3)
try:
browser.get("http://url_here")
except TimeoutException as e:
#Handle your exception here
print(e)
finally:
browser.quit()
//Java
WebDriver webdriver = new PhantomJSDriver();
webdriver.manage().timeouts()
.pageLoadTimeout(3, TimeUnit.SECONDS)
.implicitlyWait(3, TimeUnit.SECONDS);
try {
webdriver.get("http://url_here");
} catch (org.openqa.selenium.TimeoutException e) {
//Handle your exception here
System.out.println(e.getMessage());
} finally {
webdriver.quit();
}