【问题标题】:Headless browsers and Windows Azure Websites无头浏览器和 Windows Azure 网站
【发布时间】:2013-09-20 10:37:10
【问题描述】:

我正在尝试使用无头浏览器进行抓取,以便在我正在开发的开源项目中添加 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);
    }                      
}

谢谢!!

【问题讨论】:

    标签: azure selenium-webdriver phantomjs headless-browser


    【解决方案1】:

    你不能在共享网站环境中执行exe文件,要么你必须使用网络服务,要么你必须设置一个合适的(天蓝色)虚拟机。

    免费的共享网站服务真的很基础,当你需要更高级的功能时不会削减它。

    查看这个问题和接受的答案以获得更详细的答案:Can we run windowservice or EXE in Azure website or in Virtual Machine?

    【讨论】:

    • 您好,谢谢您的回答。我猜是。因为我想留在 Azure 网站,所以我会尝试使用运行幻像的在线服务,比如 Blitline,它似乎工作得很好。
    • 这个答案是不正确的。我已经在 Azure 网站上成功使用了节点,至于 PhantomJs - 目前正在尝试让它工作,当前的问题是 PhantomJs 看不到网络名称,并且如果没有设置超时,脚本将不会停止
    • @DmitryDzygin 你找到解决方案了吗?我遇到同样的问题
    • @OakNinja 我能够在 Azure Standart 网站中执行 ffmpeg.exe,但无头浏览器仍然失败。
    • @Freshblood 有人发现该问题与使用 GDI 组件的 PhantomJs 有关,并且在共享 WAWS 上被阻止 stackoverflow.com/questions/22900225/… 从微软人员的回复来看 - 不太可能随时修复很快。
    【解决方案2】:

    我不确定共享和基本网站环境,但我已成功从标准网站环境运行 ffmpeg.exe。尽管如此,phantomjs 甚至 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");
    

    【讨论】:

    • 在 Azure Web 作业中运行代码时,我收到“无法在 45000 毫秒内启动套接字。尝试连接到以下地址:127.0.0.1:7055”。有什么建议吗?
    • 我没有在Azure Web Job中使用过...只是在网站环境中尝试一下。
    • 刚在网站环境下试了一下。我收到错误消息:“System.Net.Sockets.SocketException:尝试以访问权限禁止的方式访问套接字”
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-12-29
    • 1970-01-01
    • 2019-05-11
    • 1970-01-01
    • 2010-10-23
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多