Проблема с XPath - PullRequest
       6

Проблема с XPath

1 голос
/ 05 июня 2011

Вот ссылка:

http://www.covers.com/pageLoader/pageLoader.aspx?page=/data/nba/results/2010-2011/boxscore819588.html

Я использую HTML Agility Pack, и я хотел бы извлечь, скажем, 188 из столбца «Коэффициенты». Мой редактор выдает /html/body/form/div/div[2]/div/table/tr/td[2]/div/table/tr[3]/td[7] при запросе пути. Я пробовал этот путь с различными пропусками body или html, но ни один из них не дал никаких результатов при передаче на .DocumentNode.SelectNodes() Я также попытался с // в начале (который, я полагаю, является корнем дерева документа). Что дает?

EDIT:

Код:

        WebClient client = new WebClient();
        string html = client.DownloadString(url);
        HtmlDocument doc = new HtmlDocument();
        doc.LoadHtml(html);

        foreach(HtmlNode node in doc.DocumentNode.SelectNodes("/some/xpath/expression"))
        {
            Console.WriteLine("[" + node.InnerText + "]");
        }

Ответы [ 3 ]

1 голос
/ 06 июня 2011

При очистке сайтов вы не можете безопасно полагаться на точный XPATH, предоставленный инструментами, поскольку в целом они слишком ограничительны и фактически ничего не ловят большую часть времени. Лучший способ - взглянуть на HTML и определить что-то более устойчивое к изменениям.

Вот фрагмент кода, который работает с вашим примером:

    HtmlAgilityPack.HtmlDocument doc = new HtmlAgilityPack.HtmlDocument();
    doc.Load(your html);

    foreach (HtmlNode node in doc.DocumentNode.SelectNodes("//a[text()='MIA']/ancestor::tr/td[7]"))
    {
        Console.WriteLine(node.InnerText.Trim());
    }

выводит 188.

Как это работает:

  • выберите элемент A с внутренним текстом, установленным в «MIA»
  • найти родительский элемент TR этого элемента A
  • добраться до седьмого TD этого элемента TR
  • и затем мы используем свойство InnerText этого элемента TD
1 голос
/ 05 июня 2011

Попробуйте это:

/html/body/form/div/div[2]/div/table/*/tr/td[2]/div/table/*/tr[3]/td[7]

* перехватывает обязательный элемент <tbody>, который является частью DOM-представления таблиц, даже если он не обозначен в HTML.

Кроме этого, более надежно выбирать по идентификатору, имени класса CSS или другому уникальному свойству, а не по иерархии и структуре документа:

//table[@class='data']//tr[3]/td[7]
0 голосов
/ 08 июня 2011

По умолчанию HtmlAgilityPack обрабатывает тег формы по-разному (поскольку теги формы могут перекрываться), поэтому вам нужно удалить тег формы из xpath, например: / html / body // div / div [2] / div / table / tr / тд [2] / DIV / стол / тр [3] / тд [7] * * +1001

Другой способ - заставить HtmlAgilityPack обрабатывать тег формы как другие:

HtmlNode.ElementsFlags.Remove("form");
...