PhantomJS传递HTML字符串并返回页面源代码



对于 C# 中的网络爬虫项目,我尝试执行 Javascript 和 Ajax 来检索已爬网页面的完整页面源代码。

我正在使用需要有效 HttpWebResponse 对象的现有网络爬虫 (Abot)。因此,我不能简单地使用driver.Navigate().GoToUrl()方法来检索页面源代码。

爬虫下载页面源代码,我想在源代码中执行现有的Javascript/Ajax。

在一个示例项目中,我尝试了以下内容,但没有成功:

        WebClient wc = new WebClient();
        string content = wc.DownloadString("http://www.newegg.com/Product/Product.aspx?Item=N82E16834257697");
        string tmpPath = Path.Combine(Path.GetTempPath(), "temp.htm");
        File.WriteAllText(tmpPath, content);
        var driverService = PhantomJSDriverService.CreateDefaultService();            
        var driver = new PhantomJSDriver(driverService);
        driver.Navigate().GoToUrl(new Uri(tmpPath));
        string renderedContent = driver.PageSource;
        driver.Quit();

需要以下 nuget 包才能运行示例:https://www.nuget.org/packages/phantomjs.exe/http://www.nuget.org/packages/selenium.webdriver

这里的问题是代码在 GoToUrl() 处停止,需要几分钟才能直到程序终止,甚至没有给我驱动程序。页面源。

这样做会返回正确的 HTML:

driver.Navigate().GoToUrl("http://www.newegg.com/Product/Product.aspx?Item=N82E16834257697");
string renderedContent = driver.PageSource;

但我不想下载两次数据。爬虫(Abot)下载HTML,我只想解析/渲染javascript和ajax。

谢谢!

如果不运行它,我敢打赌你需要在tmpPath之前 file:///。 那是:

    WebClient wc = new WebClient();
    string content = wc.DownloadString("http://www.newegg.com/Product/Product.aspx?Item=N82E16834257697");
    string tmpPath = Path.Combine(Path.GetTempPath(), "temp.htm");
    File.WriteAllText(tmpPath, content);
    var driverService = PhantomJSDriverService.CreateDefaultService();            
    var driver = new PhantomJSDriver(driverService);
    driver.Navigate().GoToUrl(new Uri("file:///" + tmpPath));
    string renderedContent = driver.PageSource;
    driver.Quit();

您可能需要允许 PhantomJS 发出任意请求。当域/协议不匹配时,请求将被阻止,就像打开本地文件时一样。

var driverService = PhantomJSDriverService.CreateDefaultService();
driverService.LocalToRemoteUrlAccess = true;
driverService.WebSecurity = false; // may not be necessary
var driver = new PhantomJSDriver(driverService);

您可能需要将其与Dave Bush的解决方案相结合:

driver.Navigate().GoToUrl(new Uri("file:///" + tmpPath));

某些资源的 URL 以 // 开头,这意味着当浏览器检索这些资源时,将使用页面的协议。读取本地文件时,将file://此协议,在这种情况下,将找不到这些资源。必须将协议添加到本地文件才能下载所有这些资源。

File.WriteAllText(tmpPath, content.Replace('"//', '"http://'));

从您的输出中可以明显看出您使用的是 PhantomJS 1.9.8。可能是新引入的错误负责这种事情。您应该使用带有 driverService.SslProcotol = 'tlsv1' 的 PhantomJS 1.9.7 。


如果对同一域多次执行此操作,则还应启用磁盘缓存。否则,每次尝试抓取资源时都会下载资源。这可以通过driverService.DiskCache = true;来完成

最新更新