用 C# 抓取 JavaScript 生成的网页

IT技术 c# javascript html visual-studio web-scraping
2021-02-08 18:29:56

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

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

有没有办法可以抓取页面帖子JavaScript加载?

3个回答

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

概括地说,这些是步骤:

  1. 安装selenium:http : //docs.seleniumhq.org/
  2. 启动 selenium hub 作为服务
  3. 已下载 phantomjs(无头浏览器,可以执行 javascript):http ://phantomjs.org/
  4. 在 webdriver 模式下启动 phantomjs 指向 selenium hub
  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");
我试过了,但 driver.Url 没有改变。也不例外。只要通过,它仍然是 action:blank。所以导航返回像<html><html/>。我尝试了另一个网址。请稍等,然后转到下一行。代码末尾当然找不到 some-id。任何的想法?
2021-04-05 18:29:56
感谢完美的例子。完美运行。
2021-04-09 18:29:56

多亏了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/{YOUT_API_KEY}/",
            pageRequestJson).Result;
        return response.Content.ReadAsStringAsync().Result;
    }
}

是的。

服务很好但是很慢
2021-03-26 18:29:56

好的,我将向您展示如何使用 phantomjs 和 selenuim 和 c# 启用 javascript

  1. 创建一个新的控制台项目,根据需要命名
  2. 转到右手边的解决方案资源管理器
  3. 右键单击引用单击管理 NuGet 包
  4. 一个窗口将显示点击浏览而不是安装 Selenium.WebDriver
  5. 从这里降级 phantomjs Phantomjs
  6. 在您的主函数中输入此代码

        var options = new PhantomJSOptions();
        options.AddAdditionalCapability("IsJavaScriptEnabled", true);
        IWebDriver driver = new PhantomJSDriver("phantomjs Folder Path", options);
        driver.Navigate().GoToUrl("https://www.yourwebsite.com/");
    
        try
        {
            string pagesource = driver.PageSource;
            driver.FindElement(By.Id("yourelement"));
            Console.Write("yourelement founded");
    
        }
        catch (Exception e)
        {
            Console.WriteLine(e.Message);
    
        }
    
        Console.Read();
    

不要忘记将您的网站和您要查找的元素以及您机器中的 phantomjs.exe 路径放在下面的代码中

度过了愉快的编码时光,感谢wbennett