4.爬虫框架Clawler 爬取优酷电影名 分页+多线程

代码下载地址:

https://github.com/happlyfox/FoxCrawler/tree/master/%E5%AD%A6%E4%B9%A0%E7%A4%BA%E4%BE%8B/YouKuCrawler/YouKuDotnetSpider2Async

基于文章三我们实现了爬虫框架单页面应用程序的代码,那么在这一章节我们将使用框架进行内容分页和多线程的操作

首先附上代码

public class YouKuCrawer
    {
        private static readonly string _url = "http://list.youku.com/category/video/c_0.html";

        /// <summary>
        ///     得到所有的类别
        /// </summary>
        public static List<VideoType> GetVideoTypes()
        {
            //加载web内容
            var web = new HtmlWeb();
            var doc = web.Load(_url);

            //内容解析-获得所有的类别
            var allTypes = doc.DocumentNode.SelectNodes("//*[@id='filterPanel']/div/ul/li/a").ToList();

            //类别列表中去掉【全部】这个选项
            var typeResults = allTypes.Where((u, i) => { return i > 0; }).ToList();

            var reList = new List<VideoType>();
            foreach (var node in typeResults)
            {
                var href = node.Attributes["href"].Value;
                reList.Add(new VideoType
                {
                    Code = href.Substring(href.LastIndexOf("/") + 1, href.LastIndexOf(".") - href.LastIndexOf("/") - 1),
                    Name = node.InnerText
                });
            }
            return reList;
        }

        /// <summary>
        ///     得到当前类别的总页数
        /// </summary>
        public static int GetPageCountByCode(string code)
        {
            var web = new HtmlWeb();
            var doc = web.Load($"http://list.youku.com/category/show/{code}.html");

            //分页列表
            var pageList = doc.DocumentNode.CssSelect(".yk-pages li").ToList();
            //得到倒数第二项
            var lastsecond = pageList[pageList.Count - 2];
            return Convert.ToInt32(lastsecond.InnerText);
        }
    }

因为所有的页面内容都相同,只是网站地址(url)不同,所以我首先得到所有的地址集合,然后赋给框架,让框架识别。

            // 添加初始采集链接
           //  定义采集的 Site 对象, 设置 Header、Cookie、代理等
            var site = new Site { EncodingName = "UTF-8" };
            foreach (var node in YouKuCrawer.GetVideoTypes())
            {
                //得到当前类别总分页数
                var pageCount = YouKuCrawer.GetPageCountByCode(node.Code);
                for (int pageIndex = 1; pageIndex <= pageCount; pageIndex++)
                {
                    site.AddStartUrl($"http://list.youku.com/category/show/{node.Code}_s_1_d_1_p_{pageIndex}.html");
                }
            }

首先定时采集的site对象,然后site对象添加需要解析的相同的url。在上述操作完成后,我们开始进行“解析器”类和“管道”类的书写。

解析器类

 public class YoukuPipeline : BasePipeline
    {
        public override void Process(IEnumerable<ResultItems> resultItems, ISpider spider)
        {
            var resultItem= resultItems.FirstOrDefault();

            foreach (VideoContent entry in resultItem.GetResultItem("VideoResult"))
            {
                Console.WriteLine($"{entry.Title}\t\t{entry.Href}");
            }
        }
    }

管道类

 public class YoukuPipeline : BasePipeline
    {
        public override void Process(IEnumerable<ResultItems> resultItems, ISpider spider)
        {
            var resultItem= resultItems.FirstOrDefault();

            foreach (VideoContent entry in resultItem.GetResultItem("VideoResult"))
            {
                Console.WriteLine($"{entry.Title}\t\t{entry.Href}");
            }
        }
    }

最后对定义的内容进行整理

 public static void CustmizeProcessorAndPipeline()
       {
           //  定义采集的 Site 对象, 设置 Header、Cookie、代理等
           var site = new Site { EncodingName = "UTF-8" };

           // 添加初始采集链接
           foreach (var node in YouKuCrawer.GetVideoTypes())
           {
               //得到当前类别总分页数
               var pageCount = YouKuCrawer.GetPageCountByCode(node.Code);
               for (int pageIndex = 1; pageIndex <= pageCount; pageIndex++)
               {
                   site.AddStartUrl($"http://list.youku.com/category/show/{node.Code}_s_1_d_1_p_{pageIndex}.html");
               }
           }

           Spider spider = Spider.Create(site,
                   // 使用内存调度
                   new QueueDuplicateRemovedScheduler(),
                   // 为优酷自定义的 Processor
                   new YoukuPageProcessor())
               //为优酷自定义的 Pipeline
               .AddPipeline(new YoukuPipeline());

           spider.Downloader = new HttpClientDownloader();
           spider.ThreadNum = 10;
           spider.EmptySleepTime = 3000;

           // 启动爬虫
           spider.Run();

       }

线程定义

  spider.ThreadNum = 10;

只需要通过自己的要求来进行赋值,框架自动识别内容优化线程操作。很方便

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏张善友的专栏

RESTful WCF

相较 WCF、WebService 使用 SOAP、WSDL、WS-* 而言,几乎所有的语言和网络平台都支持 HTTP 请求。我们无需去实现复杂的客户端代理,无...

19110
来自专栏张善友的专栏

.NET程序优化(GCServer )

现在的服务器都是多个cpu,在.NET Framework 2.0在GC上有个新特性GCServer ,不知道有多少人用过这个东东。 关于GC可以看这篇文章GC...

2257
来自专栏LIN_ZONE

Laravel使用Form(转载)

laravel到了5.1.*以上版本,便没有了illuminate/html类库的支持,

732
来自专栏技术之路

lock小记

都快把lock忘了用wcf 给手持设备做服务的时候可能会有并发操作但又忘了lock的使用情况 做个小例子,怕自己再忘了 不加lock的时候 结果可能 是负的下面...

1926
来自专栏木宛城主

SharePoint 2013自定义Providers在基于表单的身份验证(Forms-Based-Authentication)中的应用

由于项目的需要,登录SharePoint Application的用户将从一个统一平台中获取,而不是从Domain中获取,所以需要对SharePoint Ap...

2329
来自专栏林德熙的博客

How to parse version range

Now we are making a solution that has to get the package reference. But the vers...

630
来自专栏张善友的专栏

WCF服务中操作FormsAuthentication的Cookie

在asp.net 应用程序和WCF服务之间共享FormsAuthentication,默认是不支持的,设置一下非常的简单,只需要两步就可以了: 1、在web.c...

2095
来自专栏晓晨的专栏

.NET Core 开源工具 IPTools - 快速查询 IP 地理位置、经纬度信息

快速查询中国IP地址信息,包含国家、省份、城市、和网络运营商。非中国IP只支持查询国家。

861
来自专栏菩提树下的杨过

"RDLC"报表-参数传递及主从报表

今天继续学习RDLC报表的“参数传递”及“主从报表” 一、先创建DataSet,如下图: ? 二、创建一个报表rptDEPT.rdlc,显示部门T_DPET的数...

2416
来自专栏菩提树下的杨过

winform运行时如何接受参数?(示例)

关键是在Main函数中处理,示例如下 using System; using System.Collections.Generic; using Syste...

2428

扫码关注云+社区