3

開発中のオープン ソース プロジェクトに SEO 機能を追加するために、クロール目的でヘッドレス ブラウザを使用しようとしています。

プロジェクト サンプル サイトは、Azure Web サイトを介してデプロイされます。

Selenium .NET (PhantomJSDriver、HTMLUnitDriver、...) やスタンドアロンの PhantomJs .exe ファイルなどのさまざまなソリューションを使用して、タスクを機能させるいくつかの方法を試しました。

サイトが DurandalJS に基づいているため、私はヘッドレス ブラウザーを使用しています。生成された HTML を返すには、スクリプトを実行し、条件が true になるのを待つ必要があります。このため、WebClient/WebResponse クラスや HTMLAgilityPack など、JavaScript 以外のサイトでは問題なく機能していたものは使用できません。

上記の方法はすべて、devbox localhost 環境で機能しますが、サイトを Azure Web サイトにアップロードするときに問題が発生します。スタンドアロンの 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 Websites にとどまる必要があります。

Azure Web サイトでヘッドレス ブラウザーを実行することは可能ですか? この種の状況の経験がある人はいますか?

スタンドアロンの 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);
    }                      
}

ありがとう!!

4

2 に答える 2

3

共有 Web サイト環境で exe ファイルを実行することはできません。Web サービスを使用するか、適切な (Azure) 仮想マシンをセットアップする必要があります。

無料の共有 Web サイト サービスは非常に基本的なものであり、より高度な機能が必要な場合には役に立ちません。

より詳細な回答については、この質問と受け入れられた回答を参照してください: Can we run windowservice or EXE in Azure website or in Virtual Machine?

于 2013-09-21T07:54:53.007 に答える
0

共有および基本的な Web サイト環境についてはわかりませんが、標準の Web サイト環境から ffmpeg.exe を正常に実行できます。それにもかかわらず、phantomjs や chromedriver 自体も動作していません。ただし、Firefox ドライバーを正常に実行できます。そのためには

最新のFirefoxディレクトリをローカルからWebサイトにコピーしたところ、以下のコードがうまく機能しました。

var binary = new FirefoxBinary("/websitefolder/blabla/firefox.exe");
var driver = new FirefoxDriver(binary, new FirefoxProfile());
driver.Navigate().GoToUrl("http://www.google.com");
于 2014-12-02T09:06:21.903 に答える