Фактическая проблема заключается в том, что XPath запросов типа //tbody/tr[" + i + "]/td[5]/span
возвращает ноль , поскольку отсутствует соответствующий элемент span
HTML, и поэтому .InnerText
аварийно завершает работу с NullReferenceException
.Также индексы td
элементов (например, td[5]
), похоже, неверны.Правильный XPath равен //tbody/tr[" + i + "]/td[6]
.Но вы можете переписать свой код, чтобы сделать его намного лучше.
Поскольку вы хотите выполнять итерацию по нескольким узлам продукта, лучше использовать doc.DocumentNode.SelectNodes()
, который возвращает набор всех совпадающих узлов (продуктов) вместо doc.DocumentNode.SelectSingleNode()
.Каждый выбранный узел продукта выглядит примерно так:
<tr style="padding: 0px 10px 0px 10px; color:#000000; height:40px;" bgcolor="#EDEDED">
<td align="left" width="125"> <a href="/?ordernow=y&rem=order&prod=1"><img src="http://www.provincialtire.net/images/redcross.png"></a> 00959</td>
<td align="center"><img title="" width="75" height="27" src="http://www.provincialtire.net/provt/images/plugins/logo/UNIR.gif"></td>
<td align="center"> 4 </td>
<td align="left">-</td><td> <img width="30" src="http://www.provincialtire.net/provt/images/plugins/type/W.png"> </td>
<td align="left"> 205/60R16 Tiger Paw Ice & Snow 3 </td>
<td align="right"><div id="each1"><b></b></div></td><td style="background-image:url(/images/special.gif); background-repeat:no-repeat; background-position:top" align="center"><b>95.00</b></td>
</tr>
Если этот узел уже выбран, вам не нужно снова выполнять сложный XPath запрос, например /html/body/table/tbody/tr/td/table[2]/tbody/tr/td/table[1]/tbody/tr[1]/td[2]/table[2]/tbody/tr[1]/td/div[2]/div[1]/table/tbody/tr/td/table/tbody/tr[" + i + "]/td[1]
, чтобы собрать нужные кускиинформации.Выполните запрос XPath только против выбранного ранее узла HTML, например, node.SelectSingleNode("td[1]")
, который не только намного короче и удобочитаемее, но и более эффективен.Весь код может выглядеть следующим образом:
HtmlAgilityPack.HtmlDocument doc = new HtmlAgilityPack.HtmlDocument();
doc.LoadHtml(webBrowser1.Document.GetElementById("tablemasterbleue").InnerHtml);
foreach(var node in doc.DocumentNode
.SelectNodes("/html/body/table/tbody/tr/td/table[2]/tbody/tr/td/table[1]/tbody/tr[1]/td[2]/table[2]/tbody/tr[1]/td/div[2]/div[1]/table/tbody/tr/td/table/tbody/tr")
.Skip(1)/*Skip first row containing headers*/)
{
string Code_de_ligne = "";
string Numero_de_produit = node.SelectSingleNode("td[1]").InnerText;
string Desc_prod = node.SelectSingleNode("td[6]").InnerText;
string Prix_coutânt = node.SelectSingleNode("td[8]").InnerText;
string Prix_de_vente = "";
string Qte = node.SelectSingleNode("td[3]").InnerText;
MessageBox.Show(Code_de_ligne + "|" + Numero_de_produit + "|" + Desc_prod + " | " + Prix_coutânt + "|" + Prix_de_vente + "|" + Qte);
}
Поскольку полученные строки могут содержать избыточные объекты HTML и пробелы, например " 00959
", вам может потребоваться удалить их:
// Convert string like " 00959" to just "00959"
Numero_de_produit = HtmlEntity.DeEntitize(Numero_de_produit).Trim();