玩玩小爬虫——抓取动态页面

简介:

       在ajax横行的年代,很多网页的内容都是动态加载的,而我们的小爬虫抓取的仅仅是web服务器返回给我们的html,这其中就

跳过了js加载的部分,也就是说爬虫抓取的网页是残缺的,不完整的,下面可以看下博客园首页

从首页加载中我们看到,在页面呈现后,还会有5个ajax异步请求,在默认的情况下,爬虫是抓取不到这些ajax生成的内容的,

这时候要想获取就必须调用浏览器的内核引擎来下载这些动态页面,目前内核引擎三足鼎立。

Trident: 也就是IE内核,WebBrowser就是基于该内核,但是加载性内比较差。

Gecko: FF的内核,性能相对Trident较好。

WebKit: Safari和Chrome的内核,性能你懂的,在真实场景中还是以它为主。

好了,为了简单方便,这里使用WebBrowser来玩一把,使用WebBrowser我们要注意以下几点:

第一:因为WebBrowser在System.Windows.Forms 中,属于winform控件,所以我们要设置STAThread标记。

第二:winform是事件驱动的,而Console并不会去响事件,所有事件在windows的消息队列中等待执行,为了不让程序假死,

         我们需要调用DoEvents方法转让控制权,让操作系统执行其他的事件。

第三:WebBrowser中的内容,我们需要用DomDocument来查看,而不是DocumentText。

判断一个动态网页是否加载完毕,一般常会有两种方法:

①:设定一个最大值,因为每当异步加载一个js,都会触发一个Navigating和DocumentCompleted事件,所以我们需要在此

       处记录一下count值即可。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Threading;
using System.IO;

namespace ConsoleApplication2
{
    public class Program
    {
        static int hitCount = 0;

        [STAThread]
        static void Main(string[] args)
        {
            string url = "http://www.cnblogs.com";

            WebBrowser browser = new WebBrowser();

            browser.ScriptErrorsSuppressed = true;

            browser.Navigating += (sender, e) =>
            {
                hitCount++;
            };

            browser.DocumentCompleted += (sender, e) =>
            {
                hitCount++;
            };

            browser.Navigate(url);

            while (browser.ReadyState != WebBrowserReadyState.Complete)
            {
                Application.DoEvents();
            }

            while (hitCount < 16)
                Application.DoEvents();

            var htmldocument = (mshtml.HTMLDocument)browser.Document.DomDocument;

            string gethtml = htmldocument.documentElement.outerHTML;

            //写入文件
            using (StreamWriter sw = new StreamWriter(Environment.CurrentDirectory + "//1.html"))
            {
                sw.WriteLine(gethtml);
            }

            Console.WriteLine("html 文件 已经生成!");

            Console.Read();
        }
    }
}

然后,我们打开生成好的1.html,看看js加载的内容是不是有了。

②: 当然除了通过判断最大值确定是否已经加载完成,我们还可以通过设定一个Timer来判断,比如3s,4s,5s后来查看

      WEBbrowser 是否加载完毕。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Threading;
using System.IO;

namespace ConsoleApplication2
{
    public class Program
    {
        [STAThread]
        static void Main(string[] args)
        {
            string url = "http://www.cnblogs.com";

            WebBrowser browser = new WebBrowser();

            browser.ScriptErrorsSuppressed = true;

            browser.Navigate(url);

            //先要等待加载完毕
            while (browser.ReadyState != WebBrowserReadyState.Complete)
            {
                Application.DoEvents();
            }

            System.Timers.Timer timer = new System.Timers.Timer();

            var isComplete = false;

            timer.Elapsed += new System.Timers.ElapsedEventHandler((sender, e) =>
            {
                //加载完毕
                isComplete = true;

                timer.Stop();
            });

            timer.Interval = 1000 * 5;

            timer.Start();

            //继续等待 5s,等待js加载完
            while (!isComplete)
                Application.DoEvents();

            var htmldocument = (mshtml.HTMLDocument)browser.Document.DomDocument;

            string gethtml = htmldocument.documentElement.outerHTML;

            //写入文件
            using (StreamWriter sw = new StreamWriter(Environment.CurrentDirectory + "//1.html"))
            {
                sw.WriteLine(gethtml);
            }

            Console.WriteLine("html 文件 已经生成!");

            Console.Read();
        }
    }
}

当然,效果依旧,就不截图了,从上面的两种写法来看,我们的WebBrowser都是放在主线程中,下面我们来看看如何放在工作线程上,

很简单,只要将该工作线程设定为STA模式即可。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Threading;

namespace ConsoleApplication2
{
    public class Program
    {
        static int hitCount = 0;

        //[STAThread]
        static void Main(string[] args)
        {
            Thread thread = new Thread(new ThreadStart(() =>
            {
                Init();
                System.Windows.Forms.Application.Run();
            }));

            //将该工作线程设定为STA模式
            thread.SetApartmentState(ApartmentState.STA);

            thread.Start();

            Console.Read();
        }

        static void Init()
        {
            string url = "http://www.cnblogs.com";

            WebBrowser browser = new WebBrowser();

            browser.ScriptErrorsSuppressed = true;

            browser.DocumentCompleted += new WebBrowserDocumentCompletedEventHandler(browser_DocumentCompleted);

            browser.Navigating += new WebBrowserNavigatingEventHandler(browser_Navigating);

            browser.Navigate(url);

            while (browser.ReadyState != WebBrowserReadyState.Complete)
            {
                Application.DoEvents();
            }

            while (hitCount < 16)
                Application.DoEvents();

            var htmldocument = (mshtml.HTMLDocument)browser.Document.DomDocument;

            string gethtml = htmldocument.documentElement.outerHTML;

            Console.WriteLine(gethtml);
        }

        static void browser_Navigating(object sender, WebBrowserNavigatingEventArgs e)
        {
            hitCount++;
        }

        static void browser_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)
        {
            hitCount++;
        }
    }
}

相关文章
|
7月前
|
数据采集 数据挖掘 Python
使用Python构建简单的Web爬虫:实现网页内容抓取与分析
本文将介绍如何使用Python编写一个简单的Web爬虫,实现对特定网页内容的抓取与分析。通过学习本文,读者将了解到如何利用Python的requests和Beautiful Soup库来获取网页内容,并通过示例演示如何解析HTML结构,提取所需信息。此外,我们还将讨论一些常见的爬虫挑战以及如何避免被网站封禁的策略。
|
4月前
|
数据采集 存储 C#
C# 爬虫技术:京东视频内容抓取的实战案例分析
C# 爬虫技术:京东视频内容抓取的实战案例分析
|
13天前
|
数据采集 前端开发 JavaScript
除了网页标题,还能用爬虫抓取哪些信息?
爬虫技术可以抓取网页上的各种信息,包括文本、图片、视频、链接、结构化数据、用户信息、价格和库存、导航菜单、CSS和JavaScript、元数据、社交媒体信息、地图和位置信息、广告信息、日历和事件信息、评论和评分、API数据等。通过Python和BeautifulSoup等工具,可以轻松实现数据抓取。但在使用爬虫时,需遵守相关法律法规,尊重网站的版权和隐私政策,合理控制请求频率,确保数据的合法性和有效性。
|
2月前
|
数据采集 Python
python爬虫抓取91处理网
本人是个爬虫小萌新,看了网上教程学着做爬虫爬取91处理网www.91chuli.com,如果有什么问题请大佬们反馈,谢谢。
28 4
|
3月前
|
数据采集 存储 监控
网络爬虫的最佳实践:结合 set_time_limit() 与 setTrafficLimit() 抓取云盘数据
本文探讨了如何利用 PHP 的 `set_time_limit()` 与爬虫工具的 `setTrafficLimit()` 方法,结合多线程和代理 IP 技术,高效稳定地抓取百度云盘的公开资源。通过设置脚本执行时间和流量限制,使用多线程提高抓取效率,并通过代理 IP 防止 IP 封禁,确保长时间稳定运行。文章还提供了示例代码,展示了如何具体实现这一过程,并加入了数据分类统计功能以监控抓取效果。
70 16
网络爬虫的最佳实践:结合 set_time_limit() 与 setTrafficLimit() 抓取云盘数据
|
2月前
|
数据采集 Web App开发 JavaScript
Selenium爬虫技术:如何模拟鼠标悬停抓取动态内容
本文介绍了如何使用Selenium爬虫技术抓取抖音评论,通过模拟鼠标悬停操作和结合代理IP、Cookie及User-Agent设置,有效应对动态内容加载和反爬机制。代码示例展示了具体实现步骤,帮助读者掌握这一实用技能。
Selenium爬虫技术:如何模拟鼠标悬停抓取动态内容
|
7月前
|
数据采集 前端开发 JavaScript
Objective-C爬虫:实现动态网页内容的抓取
Objective-C爬虫:实现动态网页内容的抓取
|
3月前
|
数据采集 存储 JavaScript
构建您的第一个Python网络爬虫:抓取、解析与存储数据
【9月更文挑战第24天】在数字时代,数据是新的金矿。本文将引导您使用Python编写一个简单的网络爬虫,从互联网上自动抓取信息。我们将介绍如何使用requests库获取网页内容,BeautifulSoup进行HTML解析,以及如何将数据存储到文件或数据库中。无论您是数据分析师、研究人员还是对编程感兴趣的新手,这篇文章都将为您提供一个实用的入门指南。拿起键盘,让我们开始挖掘互联网的宝藏吧!
|
2月前
|
数据采集
爬虫案例—抓取找歌词网站的按歌词找歌名数据
爬虫案例—抓取找歌词网站的按歌词找歌名数据
|
2月前
|
数据采集 存储
爬虫案例—根据四大名著书名抓取并存储为文本文件
爬虫案例—根据四大名著书名抓取并存储为文本文件