我正在尝试使用无头浏览器进行抓取,以便在我正在开发的开源项目中添加SEO功能。
项目示例站点通过Azure网站进行部署。
我尝试了几种使用不同解决方案(如Selenium .NET(PhantomJSDriver,HTMLUnitDriver,...)甚至是独立的PhantomJs .exe文件)来完成任务的方法。
我使用的是无头浏览器,因为该网站基于DurandalJS,所以它需要执行脚本并等待条件成立才能返回生成的HTML。出于这个原因,不能使用像WebClient / WebResponse类或HTMLAgilityPack这样的东西,它们可以很好地用于非JavaScript网站。
以上所有方法都适用于我的devbox localhost环境,但是在将网站上传到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
我认为问题在于在Azure中运行.exe文件而不是代码。我知道可以通过WebRole / WebWorkers在Azure CloudServices中运行.exe文件,但需要保留在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);
}
}
谢谢!
答案 0 :(得分:3)
您无法在共享网站环境中执行exe文件,您必须使用Web服务,或者必须设置正确的(天蓝色)虚拟机。
免费的共享网站服务非常基本,当您需要更高级的功能时,它不会削减它。
请参阅此问题并接受答案,以获得更详细的答案:Can we run windowservice or EXE in Azure website or in Virtual Machine?
答案 1 :(得分:0)
我不确定共享和基本的网站环境,但我从standart网站环境成功运行ffmpeg.exe。尽管仍然幻影,甚至chromedriver本身也无法正常工作。 但是我能够成功运行Firefox驱动程序。为了做到这一点
我将最新的firefox目录从我的本地复制到网站,下面的代码运行良好。
var binary = new FirefoxBinary("/websitefolder/blabla/firefox.exe");
var driver = new FirefoxDriver(binary, new FirefoxProfile());
driver.Navigate().GoToUrl("http://www.google.com");