使用 HTML Agility Pack 解析节点
Parsing Nodes with HTML AgilityPack
我正在尝试从该页面获取信息:http://www.wowhead.com/transmog-sets?filter=3;5;0#transmog-sets
行在检查元素时看起来像这样:
我试过这段代码,但它 return 每次在任何节点上都是空的:
public class ItemSetsTransmog
{
public string ItemSetName { get; set; }
public string ItemSetId { get; set; }
}
public partial class Fmain : Form
{
DataTable Table;
HtmlWeb web = new HtmlWeb();
public Fmain()
{
InitializeComponent();
initializeItemSetTransmogTable();
}
private async void Fmain_Load(object sender, EventArgs e)
{
int PageNum = 0;
var itemsets = await ItemSetTransmogFromPage(0);
while (itemsets.Count > 0)
{
foreach (var itemset in itemsets)
Table.Rows.Add(itemset.ItemSetName, itemset.ItemSetId);
itemsets = await ItemSetTransmogFromPage(PageNum++);
}
}
private async Task<List<ItemSetsTransmog>> ItemSetTransmogFromPage(int PageNum)
{
String url = "http://www.wowhead.com/transmog-sets?filter=3;5;0#transmog-sets";
if (PageNum != 0)
url = "http://www.wowhead.com/transmog-sets?filter=3;5;0#transmog-sets:75+" + PageNum.ToString();
var doc = await Task.Factory.StartNew(() => web.Load(url));
var NameNodes = doc.DocumentNode.SelectNodes("//*[@id=\"tab - transmog - sets\"]//div//table//tr//td//div//a");
var IdNodes = doc.DocumentNode.SelectNodes("//*[@id=\"tab - transmog - sets\"]//div//table//tr//td//div//a");
// if these are null it means the name/score nodes couldn't be found on the html page
if (NameNodes == null || IdNodes == null)
return new List<ItemSetsTransmog>();
var ItemSetNames = NameNodes.Select(node => node.InnerText);
var ItemSetIds = IdNodes.Select(node => node.InnerText);
return ItemSetNames.Zip(ItemSetIds, (name, id) => new ItemSetsTransmog() { ItemSetName = name, ItemSetId = id }).ToList();
}
private void initializeItemSetTransmogTable()
{
Table = new DataTable("ItemSetTransmogTable");
Table.Columns.Add("ItemSetName", typeof(string));
Table.Columns.Add("ItemSetId", typeof(string));
ItemSetTransmogDataView.DataSource = Table;
}
}
}
为什么我的脚本不加载任何这些节点?我该如何解决?
您的代码不会加载这些节点,因为它们不存在于由 HTML Agility Pack 拉回的 HTML 中。这可能是因为您显示的大部分标记是由 JavaScript 生成的。只需尝试检查 ItemSetTransmogFromPage() 方法中的 doc.ParsedText 属性。
Html Agility Pack 是一个 HTTP Client/Parser,它不会 运行 脚本。如果您真的需要使用此过程获取数据,那么您将需要使用 "headless browser" 例如 Optimus 来检索页面(警告:我没有使用过这个库,尽管 nuget 包似乎存在)然后可能使用 HTML Agility Pack 来 parse/query 标记。
另一种方法可能是尝试解析此页面上存在的 JSON(如果这为您提供了所需的数据,尽管这似乎不太可能)。
小记——我觉得你xpath中的id应该是"tab-transmog-sets"而不是"tab - transmog - sets"
我正在尝试从该页面获取信息:http://www.wowhead.com/transmog-sets?filter=3;5;0#transmog-sets
行在检查元素时看起来像这样:
我试过这段代码,但它 return 每次在任何节点上都是空的:
public class ItemSetsTransmog
{
public string ItemSetName { get; set; }
public string ItemSetId { get; set; }
}
public partial class Fmain : Form
{
DataTable Table;
HtmlWeb web = new HtmlWeb();
public Fmain()
{
InitializeComponent();
initializeItemSetTransmogTable();
}
private async void Fmain_Load(object sender, EventArgs e)
{
int PageNum = 0;
var itemsets = await ItemSetTransmogFromPage(0);
while (itemsets.Count > 0)
{
foreach (var itemset in itemsets)
Table.Rows.Add(itemset.ItemSetName, itemset.ItemSetId);
itemsets = await ItemSetTransmogFromPage(PageNum++);
}
}
private async Task<List<ItemSetsTransmog>> ItemSetTransmogFromPage(int PageNum)
{
String url = "http://www.wowhead.com/transmog-sets?filter=3;5;0#transmog-sets";
if (PageNum != 0)
url = "http://www.wowhead.com/transmog-sets?filter=3;5;0#transmog-sets:75+" + PageNum.ToString();
var doc = await Task.Factory.StartNew(() => web.Load(url));
var NameNodes = doc.DocumentNode.SelectNodes("//*[@id=\"tab - transmog - sets\"]//div//table//tr//td//div//a");
var IdNodes = doc.DocumentNode.SelectNodes("//*[@id=\"tab - transmog - sets\"]//div//table//tr//td//div//a");
// if these are null it means the name/score nodes couldn't be found on the html page
if (NameNodes == null || IdNodes == null)
return new List<ItemSetsTransmog>();
var ItemSetNames = NameNodes.Select(node => node.InnerText);
var ItemSetIds = IdNodes.Select(node => node.InnerText);
return ItemSetNames.Zip(ItemSetIds, (name, id) => new ItemSetsTransmog() { ItemSetName = name, ItemSetId = id }).ToList();
}
private void initializeItemSetTransmogTable()
{
Table = new DataTable("ItemSetTransmogTable");
Table.Columns.Add("ItemSetName", typeof(string));
Table.Columns.Add("ItemSetId", typeof(string));
ItemSetTransmogDataView.DataSource = Table;
}
}
}
为什么我的脚本不加载任何这些节点?我该如何解决?
您的代码不会加载这些节点,因为它们不存在于由 HTML Agility Pack 拉回的 HTML 中。这可能是因为您显示的大部分标记是由 JavaScript 生成的。只需尝试检查 ItemSetTransmogFromPage() 方法中的 doc.ParsedText 属性。
Html Agility Pack 是一个 HTTP Client/Parser,它不会 运行 脚本。如果您真的需要使用此过程获取数据,那么您将需要使用 "headless browser" 例如 Optimus 来检索页面(警告:我没有使用过这个库,尽管 nuget 包似乎存在)然后可能使用 HTML Agility Pack 来 parse/query 标记。
另一种方法可能是尝试解析此页面上存在的 JSON(如果这为您提供了所需的数据,尽管这似乎不太可能)。
小记——我觉得你xpath中的id应该是"tab-transmog-sets"而不是"tab - transmog - sets"