上一章节中咱们实现了对优酷单页面的爬取,简略进行回顾一下,应用 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/categor…{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