HTMLAgilityPack 通过 div 从第一次迭代中选择节点
HTMLAgilityPack selects nodes from first iteration through divs
我第一次尝试使用 HTMLAgilityPack 解析某些网站。一切都按预期工作,但仅适用于第一次迭代。在每次迭代中,我的数据都是唯一的 div,但 SelectNodes() 总是从第一次迭代中获取数据。
下面列出的代码解释了问题
车站的所有属性都从第一次迭代中获取值。
static void Main(string[] args)
{
List<Station> stations = new List<Station>();
wClient = new WebClient();
wClient.Proxy = null;
wClient.Encoding = encode;
for (int i = 1; i <= 1; i++)
{
HtmlDocument html = new HtmlDocument();
string link = string.Format("http://energybase.ru/powerPlant/index?PowerPlant_page={0}&pageSize=20&q=/powerPlant", i);
html.LoadHtml(wClient.DownloadString(link));
var stationList = html.DocumentNode.SelectNodes("//div[@class='items']").First().ChildNodes.Where(x=>x.Name=="div").ToList();//get list of nodes with PowerStation Data
foreach (var item in stationList) //each iteration returns Item with unique InnerHTML
{
Station st = new Station();
st.Name = item.SelectNodes("//div[@class='col-md-20']").First().SelectNodes("//div[@class='name']").First().ChildNodes["a"].InnerText;//gets name from first iteration
st.Url = item.SelectNodes("//div[@class='col-md-20']").First().SelectNodes("//div[@class='name']").First().ChildNodes["a"].Attributes["href"].Value;//gets url from first iteration and so on
st.Company = item.SelectNodes("//div[@class='col-md-20']").First().SelectNodes("//div[@class='name']").First().ChildNodes["small"].ChildNodes["em"].ChildNodes["a"].InnerText;
stations.Add(st);
}
}
也许我没有掌握 OOP 的一些要点?
此 article 包含有关 html 敏捷包各个方面的一些很好的示例。
看看这篇文章,它会让你快速入门。
使用 XPath 的全部功能可以大大简化您的代码。
var stationList = html.DocumentNode.SelectNodes("//div[@class='items']/div");
// XPath-expression may be so: "//div[@class='items'][1]/div"
// where [1] means first node
foreach (var item in stationList)
{
Station st = new Station();
st.Name = item.SelectSingleNode("div[@class='col-md-20']/div[@class='name']/a").InnerText;
st.Url = item.SelectSingleNode("div[@class='col-md-20']/div[@class='name']/a").Attributes["href"].Value;
string rawText = item.SelectSingleNode("div[@class='col-md-20']/div[@class='name']/small/em").InnerText;
st.Company = HttpUtility.HtmlDecode(rawText.Trim());
stations.Add(st);
}
你的错误是使用了 XPath descendants
轴://div
.
更好的重写代码如下:
var divName = item.SelectSingleNode("div[@class='col-md-20']/div[@class='name']");
var nodeA = divName.SelectSingleNode("a");
st.Name = nodeA.InnerText;
st.Url = nodeA.Attributes["href"].Value;
string rawText = divName.SelectSingleNode("small/em").InnerText;
st.Company = HttpUtility.HtmlDecode(rawText.Trim());
我第一次尝试使用 HTMLAgilityPack 解析某些网站。一切都按预期工作,但仅适用于第一次迭代。在每次迭代中,我的数据都是唯一的 div,但 SelectNodes() 总是从第一次迭代中获取数据。 下面列出的代码解释了问题
车站的所有属性都从第一次迭代中获取值。
static void Main(string[] args)
{
List<Station> stations = new List<Station>();
wClient = new WebClient();
wClient.Proxy = null;
wClient.Encoding = encode;
for (int i = 1; i <= 1; i++)
{
HtmlDocument html = new HtmlDocument();
string link = string.Format("http://energybase.ru/powerPlant/index?PowerPlant_page={0}&pageSize=20&q=/powerPlant", i);
html.LoadHtml(wClient.DownloadString(link));
var stationList = html.DocumentNode.SelectNodes("//div[@class='items']").First().ChildNodes.Where(x=>x.Name=="div").ToList();//get list of nodes with PowerStation Data
foreach (var item in stationList) //each iteration returns Item with unique InnerHTML
{
Station st = new Station();
st.Name = item.SelectNodes("//div[@class='col-md-20']").First().SelectNodes("//div[@class='name']").First().ChildNodes["a"].InnerText;//gets name from first iteration
st.Url = item.SelectNodes("//div[@class='col-md-20']").First().SelectNodes("//div[@class='name']").First().ChildNodes["a"].Attributes["href"].Value;//gets url from first iteration and so on
st.Company = item.SelectNodes("//div[@class='col-md-20']").First().SelectNodes("//div[@class='name']").First().ChildNodes["small"].ChildNodes["em"].ChildNodes["a"].InnerText;
stations.Add(st);
}
}
也许我没有掌握 OOP 的一些要点?
此 article 包含有关 html 敏捷包各个方面的一些很好的示例。
看看这篇文章,它会让你快速入门。
使用 XPath 的全部功能可以大大简化您的代码。
var stationList = html.DocumentNode.SelectNodes("//div[@class='items']/div");
// XPath-expression may be so: "//div[@class='items'][1]/div"
// where [1] means first node
foreach (var item in stationList)
{
Station st = new Station();
st.Name = item.SelectSingleNode("div[@class='col-md-20']/div[@class='name']/a").InnerText;
st.Url = item.SelectSingleNode("div[@class='col-md-20']/div[@class='name']/a").Attributes["href"].Value;
string rawText = item.SelectSingleNode("div[@class='col-md-20']/div[@class='name']/small/em").InnerText;
st.Company = HttpUtility.HtmlDecode(rawText.Trim());
stations.Add(st);
}
你的错误是使用了 XPath descendants
轴://div
.
更好的重写代码如下:
var divName = item.SelectSingleNode("div[@class='col-md-20']/div[@class='name']");
var nodeA = divName.SelectSingleNode("a");
st.Name = nodeA.InnerText;
st.Url = nodeA.Attributes["href"].Value;
string rawText = divName.SelectSingleNode("small/em").InnerText;
st.Company = HttpUtility.HtmlDecode(rawText.Trim());