使用 C# 抓取由 JavaScript 生成的网页

新手上路,请多包涵

我有一个网络浏览器,在 Visual Studio 中有一个标签,基本上我想做的是从另一个网页上抓取一个部分。

我尝试使用 WebClient.DownloadStringWebClient.DownloadFile ,它们都在 JavaScript 加载内容之前给了我网页的源代码。我的下一个想法是使用网络浏览器工具,并在页面加载后调用 webBrowser.DocumentText 但它不起作用,它仍然为我提供页面的原始来源。

有没有一种方法可以获取页面帖子 JavaScript 加载?

原文由 Prokzy 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 670
2 个回答

问题是浏览器通常会执行 javascript 并且会导致更新的 DOM。除非您可以分析 javascript 或拦截它使用的数据,否则您将需要像浏览器一样执行代码。过去我遇到过同样的问题,我使用 selenium 和 PhantomJS 来渲染页面。呈现页面后,我将使用 WebDriver 客户端导航 DOM 并检索我需要的内容,发布 AJAX。

在高层次上,这些是步骤:

  1. 安装硒:http: //docs.seleniumhq.org/
  2. 启动 selenium hub 作为服务
  3. 下载的 phantomjs(无头浏览器,可以执行 javascript): http://phantomjs.org/
  4. 以指向 selenium hub 的 webdriver 模式启动 phantomjs
  5. 在我的抓取应用程序中安装了 webdriver 客户端 nuget 包: Install-Package Selenium.WebDriver

以下是 phantomjs webdriver 的示例用法:

 var options = new PhantomJSOptions();
options.AddAdditionalCapability("IsJavaScriptEnabled",true);

var driver = new RemoteWebDriver( new URI(Configuration.SeleniumServerHub),
                    options.ToCapabilities(),
                    TimeSpan.FromSeconds(3)
                  );
driver.Url = "http://www.regulations.gov/#!documentDetail;D=APHIS-2013-0013-0083";
driver.Navigate();
//the driver can now provide you with what you need (it will execute the script)
//get the source of the page
var source = driver.PageSource;
//fully navigate the dom
var pathElement = driver.FindElementById("some-id");

有关 selenium、phantomjs 和 webdriver 的更多信息,请访问以下链接:

http://docs.seleniumhq.org/

http://docs.seleniumhq.org/projects/webdriver/

http://phantomjs.org/

编辑:更简单的方法

似乎有一个 phantomjs 的 nuget 包,这样你就不需要集线器了(我使用集群以这种方式进行大量报废):

安装网络驱动程序:

 Install-Package Selenium.WebDriver

安装嵌入式exe:

 Install-Package phantomjs.exe

更新代码:

 var driver = new PhantomJSDriver();
driver.Url = "http://www.regulations.gov/#!documentDetail;D=APHIS-2013-0013-0083";
driver.Navigate();
//the driver can now provide you with what you need (it will execute the script)
//get the source of the page
var source = driver.PageSource;
//fully navigate the dom
var pathElement = driver.FindElementById("some-id");

原文由 wbennett 发布,翻译遵循 CC BY-SA 3.0 许可协议

感谢 wbennet ,我发现了 PhantomJSCloud.com 。足够的免费服务可以通过网络 API 电话报废页面。

 public static string GetPagePhantomJs(string url)
{
    using (var client = new System.Net.Http.HttpClient())
    {
        client.DefaultRequestHeaders.ExpectContinue = false;
        var pageRequestJson = new System.Net.Http.StringContent
            (@"{'url':'" + url + "','renderType':'html','outputAsJson':false }");
        var response = client.PostAsync
            ("https://PhantomJsCloud.com/api/browser/v2/{YOUR_API_KEY}/",
            pageRequestJson).Result;
        return response.Content.ReadAsStringAsync().Result;
    }
}

是的。

原文由 Ark667 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题