Безголовые браузеры и веб-сайты Windows Azure
Я пытаюсь использовать безголовый браузер для сканирования, чтобы добавить функции SEO в проект с открытым исходным кодом, который я разрабатываю.
Пример сайта проекта разворачивается через веб-сайты Azure.
Я попробовал несколько способов заставить задачу работать, используя различные решения, такие как Selenium .NET (PhantomJSDriver, HTMLUnitDriver, ...) или даже отдельный файл PhantomJs .exe.
Я использую безголовый браузер, потому что сайт основан на DurandalJS, поэтому он должен выполнять сценарии и ожидать выполнения условия, чтобы вернуть сгенерированный HTML. По этой причине нельзя использовать такие вещи, как классы WebClient/WebResponse или HTMLAgilityPack, которые отлично работают для сайтов, не поддерживающих JavaScript.
Все вышеперечисленные методы работают в моей локальной среде devbox, но проблема возникает при загрузке сайта на веб-сайты Azure. При использовании автономных phantomjs сайт зависает при обращении к конечной точке URL и через некоторое время возвращает ошибку HTTP 502. В случае использования Selenium Webdriver я получаю
OpenQA.Selenium.WebDriverException: Unexpected error. System.Net.WebException: Unable to connect to the remote server ---> System.Net.Sockets.SocketException: No connection could be made because the target machine actively refused it 127.0.0.1:XXXX
Я думаю, что проблема с запуском.exe-файлов в Azure, а не с кодом. Я знаю, что можно запускать файлы.exe в Azure CloudServices через WebRole/WebWorkers, но для простоты необходимо оставаться на веб-сайтах Azure.
Можно ли запустить браузер без головы на веб-сайтах Azure? Кто-нибудь имеет опыт работы с такой ситуацией?
Мой код для автономного решения PhantomJS:
//ASP MVC ActionResult
public ActionResult GetHTML(string url)
{
string appRoot = Server.MapPath("~/");
var startInfo = new ProcessStartInfo
{
Arguments = String.Format("{0} {1}", Path.Combine(appRoot, "Scripts\\seo\\renderHTML.js"), url),
FileName = Path.Combine(appRoot, "bin\\phantomjs.exe"),
UseShellExecute = false,
CreateNoWindow = true,
RedirectStandardOutput = true,
RedirectStandardError = true,
RedirectStandardInput = true,
StandardOutputEncoding = System.Text.Encoding.UTF8
};
var p = new Process();
p.StartInfo = startInfo;
p.Start();
string output = p.StandardOutput.ReadToEnd();
p.WaitForExit();
ViewData["result"] = output;
return View();
}
// PhantomJS script
var resourceWait = 300,
maxRenderWait = 10000;
var page = require('webpage').create(),
system = require('system'),
count = 0,
forcedRenderTimeout,
renderTimeout;
page.viewportSize = { width: 1280, height: 1024 };
function doRender() {
console.log(page.content);
phantom.exit();
}
page.onResourceRequested = function (req) {
count += 1;
//console.log('> ' + req.id + ' - ' + req.url);
clearTimeout(renderTimeout);
};
page.onResourceReceived = function (res) {
if (!res.stage || res.stage === 'end') {
count -= 1;
//console.log(res.id + ' ' + res.status + ' - ' + res.url);
if (count === 0) {
renderTimeout = setTimeout(doRender, resourceWait);
}
}
};
page.open(system.args[1], function (status) {
if (status !== "success") {
//console.log('Unable to load url');
phantom.exit();
} else {
forcedRenderTimeout = setTimeout(function () {
//console.log(count);
doRender();
}, maxRenderWait);
}
});
и для варианта Selenium
public ActionResult GetHTML(string url)
{
using (IWebDriver driver = new PhantomJSDriver())
{
driver.Navigate().GoToUrl(url);
WebDriverWait wait = new WebDriverWait(driver, TimeSpan.FromSeconds(30));
IWebElement myDynamicElement = wait.Until<IWebElement>((d) =>
{
return d.FindElement(By.CssSelector("#compositionComplete"));
});
var content = driver.PageSource;
driver.Quit();
return Content(content);
}
}
Спасибо!!
2 ответа
Вы не можете запускать exe-файлы в среде общего веб-сайта, либо вы должны использовать веб-сервисы, либо вы должны настроить правильную (лазурную) виртуальную машину.
Бесплатный общедоступный веб-сайт действительно простой, и его не нужно сокращать, когда вам нужны более продвинутые функциональные возможности.
См. Этот вопрос и принятый ответ для более подробного ответа: можем ли мы запустить windowservice или EXE на веб-сайте Azure или на виртуальной машине?
Я не уверен насчет общей и базовой среды веб-сайта, но я успешно запустил ffmpeg.exe из стандартной среды веб-сайта. Несмотря на это, фантомы и даже сам хромедрайвер не работают. Однако я могу успешно запустить драйвер Firefox. Для того, чтобы сделать это
Я скопировал последнюю версию каталога Firefox с моего локального сайта на веб-сайт, и код ниже работал хорошо
var binary = new FirefoxBinary("/websitefolder/blabla/firefox.exe");
var driver = new FirefoxDriver(binary, new FirefoxProfile());
driver.Navigate().GoToUrl("http://www.google.com");