HTML Agility Pack - использование XPath для получения единого узла - ссылка на объект не установлена ​​в экземпляр объекта

html-agility-pack xpath

Вопрос

это моя первая попытка получить значение элемента с помощью HAP. Когда я пытаюсь использовать InnerText, я получаю ошибку с нулевым объектом.

URL-адрес, который я очищаю: http://www.mypivots.com/dailynotes/symbol/659/-1/e-mini-sp500-june-2013. Я пытаюсь получить значение для текущего максимума из дневного изменения Таблица результатов.

Мой код внизу. Во-первых, я просто хотел бы знать, правильно ли я это сделаю? Если да, то просто ли мое значение XPath неверно?

значение XPath было получено с помощью утилиты, которую я нашел, называемой htmlagility helper. Версия firebug XPath ниже также дает ту же ошибку: - / html / body / div [3] / div / table / tbody / tr [3] / td / table / tbody / tr [5] / td [3 ]

Мой код: -

WebClient myPivotsWC = new WebClient();
string nodeValue;
string htmlCode = myPivotsWC.DownloadString("http://www.mypivots.com/dailynotes/symbol/659/-1/e-mini-sp500-june-2013");
HtmlAgilityPack.HtmlDocument doc = new HtmlAgilityPack.HtmlDocument();
doc.LoadHtml(htmlCode);
HtmlNode node = doc.DocumentNode.SelectSingleNode("/html[1]/body[1]/div[3]/div[1]/table[1]/tbody[1]/tr[3]/td[1]/table[1]/tbody[1]/tr[5]/td[3]");
nodeValue=(node.InnerText);

Спасибо, Уилл.

Принятый ответ

Вы не можете полагаться на инструменты разработки, такие как FireBug или Chrome и т. Д., Чтобы определить XPATH для тех узлов, которые вам нужны, поскольку XPATH, предоставляемый такими инструментами, соответствует памяти HTML DOM, в то время как Html Agility Pack только знает о необработанном HTML, отправленном обратно сервером.

То, что вам нужно сделать, это визуально посмотреть на то, что отправлено назад (или просто создать источник просмотра). Вы увидите, что нет элемента TBODY, например. Таким образом, вы хотите найти что-либо дискриминантное и использовать, например, оси XPATH . Кроме того, ваш XPATH, даже если он сработает, не будет очень устойчив к изменениям в документе, поэтому вам нужно найти что-то более «стабильное» для того, чтобы скребок был более надежным в будущем.

Вот код, который, похоже, работает:

HtmlNode node = doc.DocumentNode.SelectSingleNode("//td[@class='dnTableCell']//a[text()='High']/../../td[3]");

Это то, что он делает:

  • найдите элемент TD с атрибутом CLASS, установленным в 'dnTableCell'. // token означает, что поиск является рекурсивным в иерархии XML.
  • найдите элемент A, содержащий текст (внутренний текст), равный «Высокий».
  • перейдите к двум родителям (мы перейдем к ближайшему элементу TR)
  • выберите третий элемент ТД оттуда

Популярные ответы

например, Simon Mourier explaind, вы получили необработанный HTML-код, отправленный сервером. Элемент, который вам нужен, пока не отображается, потому что вы еще не можете его восстановить, поскольку он не существует в DOM. простая работа вокруг этой проблемы заключается в использовании веб-рендерера для создания DOM, чем вы можете захватить HTML и очистить его. Я использую WatiN следующим образом:

WatiN.Core.Settings.MakeNewInstanceVisible = false;
WatiN.Core.Settings.AutoMoveMousePointerToTopLeft = false; 
IE ie = new IE();
ie.GoTo(urlLink); 
ie.WaitForComplete();
string html = ie.Html;
ie.close();


Related

Лицензировано согласно: CC-BY-SA with attribution
Не связан с Stack Overflow
Лицензировано согласно: CC-BY-SA with attribution
Не связан с Stack Overflow