[DotnetSpider 系列目錄]
使用環境
-
Visual Studio 2017
-
.NET 4.5 or later or .NET Core
概述
在上一篇也講到過,實現一個完整的爬蟲需要4大模塊:下載器(已有實現),URL調度(已有實現),數據抽取(需要自己實現),數據存儲(需要自己實現),因此,只需要實現數據抽取、數據存儲這兩個模塊就可以完成一個爬蟲了。
新建一個Console 項目
- 右鍵項目的Manage NuGet Packages(管理NuGet包)
-
搜索DotnetSpider2, 從結果列表中選中DotnetSpider2.Core並安裝到控制台項目中
定義數據對象
public class YoukuVideo { public string Name { get; set; } }
定義數據抽取(實現 IPageProcessor 接口)
public class YoukuPageProcessor : BasePageProcessor { protected override void Handle(Page page) { // 利用 Selectable 查詢並構造自己想要的數據對象 var totalVideoElements = page.Selectable.SelectList(Selectors.XPath("//div[@class='yk-pack pack-film']")).Nodes(); List<YoukuVideo> results = new List<YoukuVideo>(); foreach (var videoElement in totalVideoElements) { var video = new YoukuVideo(); video.Name = videoElement.Select(Selectors.XPath(".//img[@class='quic']/@alt")).GetValue(); results.Add(video); } // Save data object by key. 以自定義KEY存入page對象中供Pipeline調用 page.AddResultItem("VideoResult", results); } }
需要注意的是
- Page 對象中Selectable屬性是由下載的HTML構造的選擇器容器,調用Seletable的接口就可以進行Xpath,Css, JsonPath,Regex的查詢
- Selectable的GetValue傳入true時會把結果去HTML標簽化
- 把組裝好的對象,如上面的 YoukuVideo List, 保存到page的ResultItem中,並指定一個唯一的Key
定義數據管道(繼承BasePipeline這個抽象類)
數據管道可以通過在PageProcessor中指定的唯一Key,取出需要處理的數據存入想要的數據庫或文件中
public class YoukuPipeline : BasePipeline { private static long count = 0; public override void Process(ResultItems resultItems) { StringBuilder builder = new StringBuilder(); foreach (YoukuVideo entry in resultItems.Results["VideoResult"]) { count++; builder.Append($" [YoukuVideo {count}] {entry.Name}"); } Console.WriteLine(builder); // Other actions like save data to DB. 可以自由實現插入數據庫或保存到文件 } }
初始化起始鏈接並運行
通過AddStartUrl可以添加爬蟲的起始鏈接后,調用Run方法運行爬蟲
// Config encoding, header, cookie, proxy etc... 定義采集的 Site 對象, 設置 Header、Cookie、代理等 var site = new Site { EncodingName = "UTF-8", RemoveOutboundLinks = true }; for (int i = 1; i < 5; ++i) { // Add start/feed urls. 添加初始采集鏈接 site.AddStartUrl($"http://list.youku.com/category/show/c_96_s_1_d_1_p_{i}.html"); } Spider spider = Spider.Create(site, // use memoery queue scheduler. 使用內存調度 new QueueDuplicateRemovedScheduler(), // use custmize processor for youku 為優酷自定義的 Processor new YoukuPageProcessor()) // use custmize pipeline for youku 為優酷自定義的 Pipeline .AddPipeline(new YoukuPipeline()); spider.Downloader = new HttpClientDownloader(); spider.ThreadNum = 1; spider.EmptySleepTime = 3000; // Start crawler 啟動爬蟲 spider.Run();
運行結果
設置目標頁抽取
以上只是采集了初始的一個鏈接,如何達到翻頁(遍歷)效果繼續采集直的最后一頁呢?只需要在PageProccessor中解析出符合規則的目標頁,並加入到Page對象的TargetRequests這個List中即可。我們做如下改動:
public class YoukuPageProcessor : BasePageProcessor { protected override void Handle(Page page) { // 利用 Selectable 查詢並構造自己想要的數據對象 var totalVideoElements = page.Selectable.SelectList(Selectors.XPath("//div[@class='yk-pack pack-film']")).Nodes(); List<YoukuVideo> results = new List<YoukuVideo>(); foreach (var videoElement in totalVideoElements) { var video = new YoukuVideo(); video.Name = videoElement.Select(Selectors.XPath(".//img[@class='quic']/@alt")).GetValue(); results.Add(video); } // Save data object by key. 以自定義KEY存入page對象中供Pipeline調用 page.AddResultItem("VideoResult", results); // Add target requests to scheduler. 解析需要采集的URL foreach (var url in page.Selectable.SelectList(Selectors.XPath("//ul[@class='yk-pages']")).Links().Nodes()) { page.AddTargetRequest(new Request(url.GetValue(), null)); } } }
重新運行爬蟲后,可以看到已經實現的翻頁
代碼地址
https://github.com/zlzforever/DotnetSpider 望各位大佬加星
參與開發或有疑問
博文寫得比較早, 框架修改有時會來不及更新博文中的代碼, 請查看DotnetSpider.Sample項目中的樣例爬蟲
QQ群: 477731655