抓取动态网页(ajax横行的年代,我们的网页是残缺的吗? )

优采云 发布时间: 2021-09-29 15:28

  抓取动态网页(ajax横行的年代,我们的网页是残缺的吗?

)

  在Ajax时代,许多网页的内容都是动态加载的,我们的小爬虫只抓取web服务器返回给我们的HTML

  跳过了JS加载部分,即爬虫抓取的网页不完整、不完整。你可以看到下面博客花园的首页

  

  从主页加载中,我们可以看到页面呈现后,将有五个Ajax异步请求。默认情况下,爬虫程序无法抓取Ajax生成的内容

  此时,如果要获取这些动态页面,必须调用浏览器的内核引擎来下载这些动态页面。目前,内核引擎有三个支柱

  三叉戟:即内核。WebBrowser基于此内核,但其可加载性较差

  壁虎:FF的内核比Trident有更好的性能

  WebKit:Safari和chrome的内核性能,你知道,在真实场景中仍然基于它

  好吧,为了简单和方便,让我们使用WebBrowser来玩。使用WebBrowser时,我们应注意以下几点:

  第一:因为WebBrowser是system.windows.forms中的WinForm控件,所以我们需要设置StatThread标志

  第二:WinForm是事件驱动的,控制台不响应事件。所有事件都在windows的消息队列中等待执行。为了不让程序假装死亡

  我们需要调用Doevents方法来转移控制,并让操作系统执行其他事件

  第三:我们需要使用domdocument而不是documenttext来查看WebBrowser中的内容

  通常有两种方法来判断是否加载了动态网页:

  ① : 在这里设置一个最大值,因为每次异步加载JS时,都会触发导航和documentcompleted事件,所以我们需要

  只需将计数值记录在

  

   1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Text; 5 using System.Windows.Forms; 6 using System.Threading; 7 using System.IO; 8  9 namespace ConsoleApplication210 {11     public class Program12     {13         static int hitCount = 0;14 15         [STAThread]16         static void Main(string[] args)17         {18             string url = "http://www.cnblogs.com";19 20             WebBrowser browser = new WebBrowser();21 22             browser.ScriptErrorsSuppressed = true;23 24             browser.Navigating += (sender, e) =>25             {26                 hitCount++;27             };28 29             browser.DocumentCompleted += (sender, e) =>30             {31                 hitCount++;32             };33 34             browser.Navigate(url);35 36             while (browser.ReadyState != WebBrowserReadyState.Complete)37             {38                 Application.DoEvents();39             }40 41             while (hitCount 35             {36                 //加载完毕37                 isComplete = true;38 39                 timer.Stop();40             });41 42             timer.Interval = 1000 * 5;43 44             timer.Start();45 46             //继续等待 5s,等待js加载完47             while (!isComplete)48                 Application.DoEvents();49 50             var htmldocument = (mshtml.HTMLDocument)browser.Document.DomDocument;51 52             string gethtml = htmldocument.documentElement.outerHTML;53 54             //写入文件55             using (StreamWriter sw = new StreamWriter(Environment.CurrentDirectory + "//1.html"))56             {57                 sw.WriteLine(gethtml);58             }59 60             Console.WriteLine("html 文件 已经生成!");61 62             Console.Read();63         }64     }65 }

  

  当然,效果是一样的,所以我们不会截图。通过以上两种编写方法,我们的WebBrowser被放置在主线程中。让我们看看如何把它放在工作线程上

  非常简单,只需将工作线程设置为sta模式

  

<p> 1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Text; 5 using System.Windows.Forms; 6 using System.Threading; 7  8 namespace ConsoleApplication2 9 {10     public class Program11     {12         static int hitCount = 0;13 14         //[STAThread]15         static void Main(string[] args)16         {17             Thread thread = new Thread(new ThreadStart(() =>18             {19                 Init();20                 System.Windows.Forms.Application.Run();21             }));22 23             //将该工作线程设定为STA模式24             thread.SetApartmentState(ApartmentState.STA);25 26             thread.Start();27 28             Console.Read();29         }30 31         static void Init()32         {33             string url = "http://www.cnblogs.com";34 35             WebBrowser browser = new WebBrowser();36 37             browser.ScriptErrorsSuppressed = true;38 39             browser.DocumentCompleted += new WebBrowserDocumentCompletedEventHandler(browser_DocumentCompleted);40 41             browser.Navigating += new WebBrowserNavigatingEventHandler(browser_Navigating);42 43             browser.Navigate(url);44 45             while (browser.ReadyState != WebBrowserReadyState.Complete)46             {47                 Application.DoEvents();48             }49 50             while (hitCount 

0 个评论

要回复文章请先登录注册


官方客服QQ群

微信人工客服

QQ人工客服


线