上一章節中我們實現了對優酷單頁面的爬取,簡單進行回顧一下,使用HtmlAgilityPack庫,對爬蟲的爬取一共分為三步
- 爬蟲步驟
- 載入頁面
- 解析資料
- 儲存資料
繼第一篇文件後的爬蟲進階,本文章主要是對上一篇的進階。實現的功能主要為:
1、爬取電影類別列表
2、迴圈每個類別的電影資訊,對每個類別的資訊分頁爬取
3、爬取的資料儲存到資料庫中
一、爬取電影類別列表
使用Chrome瀏覽器,F12,找到當前位置,得到當前位置的Xpath。我們需要的資料是電影的類別編碼和電影類別名稱。
規則分析:
XPATH路徑為 "//*[@id='filterPanel']/div/ul/li/a")
類別編碼為A標籤Href路徑的內容,我們對其進行擷取
類別名稱為A標籤InnerTest,我們對其進行擷取
程式碼示例
//載入web內容
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;
}
二、爬取每個類別的總分頁數
code 為電影類別編碼
頁面規則 $"http://list.youku.com/category/show/{code}.html"
根據頁面規則進行爬取:
/// <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);
}
三、按照頁碼得到每個電影類別的內容
根據分頁規則分析出分頁後的地址為
code 為編碼 pageIndex為第幾頁
頁面規則:http://list.youku.com/category/show/{code}s_1_d_1_p{pageIndex}.html
根據頁面規則進行爬取:
/// <summary>
/// 得到當前類別的內容
/// </summary>
public static List<VideoContent> GetContentsByCode(string code, int pageIndex)
{
var web = new HtmlWeb();
var doc = web.Load($"http://list.youku.com/category/show/{code}_s_1_d_1_p_{pageIndex}.html");
var returnLi = new List<VideoContent>();
var contents = doc.DocumentNode.CssSelect(".yk-col4").ToList();
foreach (var node in contents)
returnLi.Add(new VideoContent
{
PageIndex = pageIndex.ToString(),
Code = code,
Title = node.CssSelect(".info-list .title a").FirstOrDefault()?.InnerText,
Hits = node.CssSelect(".info-list li").LastOrDefault()?.InnerText,
Href = node.CssSelect(".info-list .title a").FirstOrDefault()?.Attributes["href"].Value,
ImgHref = node.CssSelect(".p-thumb img").FirstOrDefault()?.Attributes["Src"].Value
});
return returnLi;
}
四、測試爬取的結果
/// <summary>
/// 列印得到的內容
/// </summary>
public static void PrintContent()
{
var count = 0;
foreach (var node in GetVideoTypes())
{
var resultLi = new List<VideoContent>();
//得到當前類別總分頁數
var pageCount = GetPageCountByCode(node.Code);
//遍歷分頁得到內容
for (var i = 1; i <= pageCount; i++) resultLi.AddRange(GetContentsByCode(node.Code, i));
Console.WriteLine($"編碼{node.Code} \t 頁數{pageCount} \t 總個數{resultLi.Count}");
count += resultLi.Count;
}
Console.WriteLine($"總個數為{count}");
}
程式碼下載地址:
https://github.com/happlyfox/FoxCrawler/tree/master/%E5%AD%A6%E4%B9%A0%E7%A4%BA%E4%BE%8B/YouKuCrawler/YouKuCrawlerAsync