通過圖可知另萤,總共有N個類別,每個類別都是一個DIV區(qū)塊诅挑,然后再繼續(xù)分解DIV區(qū)塊分析內(nèi)容四敞。我們要得到的是類別表,據(jù)圖所示我們可以分析得出類別表的結(jié)構(gòu)應(yīng)當樹形的拔妥。所以涉及的表應(yīng)該是包含子節(jié)點和父節(jié)點的忿危。初步設(shè)計圖如下
Id | Pid | Code | Name | Url |
---|---|---|---|---|
主鍵 | 父節(jié)點 | 編碼 | 名稱 | 地址 |
我們可以得到解析圖2對應(yīng)的 Xpath為://*[@id="20089"]/div[2]/div[2] ∶涣可是因為是通過ID作為唯一Key來向下找铺厨,所以我們需要先得到所有的Key值。這個方法被我放棄而選用了另外一種方式硬纤。
/html/body/div[5]/div[2].首先找到如果所示xpath對應(yīng)的內(nèi)容
/html/body/div[5]/div[2].png
那么如果我們想要得到下屬的內(nèi)容只需要增加一個后綴
/html/body/div[5]/div[2]/div
此時我們得到了所有模塊的內(nèi)容解滓,那么我們接下去分析
還是以“手機配件”為例。一級類別筝家,二級類別伐蒂、三級類別如果所示。我們又如何得到內(nèi)容肛鹏,然后將其變成單元行的形式插入數(shù)據(jù)庫中呢逸邦?
解決方案如下
根據(jù)網(wǎng)頁內(nèi)容可知,一級類別包含著二級類別在扰,二級類別包含著三級類別缕减。所以我們可以采用如下方式。
首先獲取所有一級類別芒珠,即解析圖2.png所示內(nèi)容桥狡。
一級類別 A方法
循環(huán)當前內(nèi)容
1、解析內(nèi)容 增加當前A級類別實體
2、循環(huán)包含的二級內(nèi)容裹芝,處理
3部逮、合并實體
二級類別 B方法
循環(huán)當前內(nèi)容
1、解析內(nèi)容 增加當前B級類別實體
2嫂易、循環(huán)包含的三級級內(nèi)容兄朋,處理
3、返回實體給A方法
三級類別 C方法
循環(huán)當前內(nèi)容
1怜械、解析內(nèi)容 增加當前C級類別實體
2颅和、返回實體給B方法
ABC.png
代碼講解
ABC(Combine)方法
遍歷InitA方法獲取的內(nèi)容,增加A實體后將ANode作為參數(shù)傳遞給InitB方法缕允。依次類推峡扩,最后得到符合要求的實體。
private static List<POCO_Category> CombineA_B_C()
{
List<POCO_Category> AList = new List<POCO_Category>();
int idIndex = 1;
foreach (HtmlNode xNode in InitA())
{
POCO_Category aModel = new POCO_Category()
{
Id = ToLevelCode(idIndex),
PId = "000",
Levels = 1,
Code = ToLevelCode(idIndex),
Name = xNode.SelectSingleNode("./h2").InnerText
};
AList.Add(aModel);
var blist = InitB(aModel, xNode);
AList.AddRange(blist);
idIndex = idIndex + blist.Count + 1;
}
return AList;
}
private static List<HtmlNode> InitA()
{
var url = "https://list.suning.com/#20089";
var web = new HtmlWeb();
var docWeb = web.Load(url);
//var cssNodes = docWeb.DocumentNode.CssSelect(".search-main.introduce.clearfix > div").ToList();//147毫秒
List<HtmlNode> xpathNodes = docWeb.DocumentNode.SelectNodes("/html/body/div[5]/div[2]/div").ToList();
return xpathNodes;
}
private static List<POCO_Category> InitB(POCO_Category parentModel, HtmlNode node)
{
int idIndex = Convert.ToInt32(parentModel.Id) + 1;
List<POCO_Category> bList = new List<POCO_Category>();
var xNodes = node.SelectNodes("./div").ToList();
foreach (var xNode in xNodes)
{
var cateModel = xNode.SelectSingleNode("./div[1]/a");
POCO_Category bModel = new POCO_Category()
{
Id = ToLevelCode(idIndex),
PId = parentModel.Id,
Code = $"{parentModel.Code}_{ToLevelCode(idIndex)}",
Name = cateModel.InnerText,
Url = $"https:{cateModel.GetAttributeValue("href")}",
Levels = 2
};
bList.Add(bModel);
var clist = InitC(bModel, xNode.SelectSingleNode("./div[2]"));
bList.AddRange(clist);
idIndex = idIndex + clist.Count + 1;
}
return bList;
}
private static List<POCO_Category> InitC(POCO_Category parentModel, HtmlNode node)
{
int idIndex = Convert.ToInt32(parentModel.Id) + 1;
List<POCO_Category> cList = new List<POCO_Category>();
HtmlNodeCollection xNodes = node.SelectNodes("./a");
if (xNodes != null && xNodes.Count > 0)
{
foreach (var xNode in xNodes)
{
POCO_Category cModel = new POCO_Category()
{
Id = ToLevelCode(idIndex),
PId = parentModel.Id,
Code = $"{parentModel.Code}_{ToLevelCode(idIndex)}",
Name = xNode.InnerText,
Url = $"https:{xNode.GetAttributeValue("href")}",
Levels = 3
};
cList.Add(cModel);
idIndex += 1;
}
}
return cList;
}
private static string ToLevelCode(int index)
{
return index.ToString("000");
}