Вопрос об алгоритме HtmlAgilityPack - PullRequest
1 голос
/ 06 июля 2011

Я использую HtmlAgilityPack для получения HTML-кода с веб-сайта.

Вот полученный HTML:

<table class="table">
<tr>
    <td>
        <table class="innertable">...</table>
    </td>
</tr>
<tr>
    <td colspan="2"><strong>Contact</strong></td>
</tr>
<tr>
    <td colspan="2">John Doe</td>
</tr>
<tr>
    <td colspan="2">Jane Doe</td>
</tr>
<tr>
    <td colspan="2">&nbsp;</td>
</tr>
<tr>
    <td><strong>Units</strong></td>
    <td>32</td>
</tr>
<tr>
    <td><strong>Year</strong></td>
    <td>1998</td>
</tr>
</table>

Контекст:

Я использую следующий код для получения первого:

var table = document.DocumentNode.SelectNodes("//table[@class='table']").FirstOrDefault();

Я использую следующий код для получения внутренней таблицы:

var innerTable = table.SelectNodes("//table[@class=innertable]").FirstOrDefault();

Пока все хорошо!

Мне нужно получить некоторую информацию из первой таблицы, а другую - из внутренней таблицы. Поскольку я начинаю с информации из первой таблицы, мне нужно пропустить первую строку (которая содержит внутреннюю таблицу), поэтому я делаю следующее:

var tableCells = table.SelectNodes("tr[position() > 1]/td");

Поскольку теперь у меня есть все ячейки из первой таблицы, кроме внутренней таблицы, я начинаю делать следующее:

string contact1 = HttpUtility.HtmlDecode(tableCells[1].InnerHtml);
string contact2 = HttpUtility.HtmlDecode(tableCells[2].InnerHtml);

string units = HttpUtility.HtmlDecode(tableCells[5].InnerHtml);
string years = HttpUtility.HtmlDecode(tableCells[7].InnerHtml);

Проблема:

Я получаю нужные значения с помощью жесткого кодирования индекса в tableCells [], не думая, что макет будет перемещаться ... к сожалению, он действительно перемещается.

В некоторых случаях у меня нет строки «Джейн Доу» (как показано в приведенном выше HTML), это означает, что у меня или может не быть двух контактов.

Из-за этого я не могу жестко закодировать индексы, поскольку в результате я могу получить неправильные данные в неправильных переменных.

Так что мне нужно изменить свой подход ...

Кто-нибудь знает, как я мог бы усовершенствовать свой алгоритм, чтобы он мог учитывать тот факт, что у меня может быть один или два контакта и, возможно, я не использую жестко закодированные индексы?

Заранее спасибо!

vlince

1 Ответ

1 голос
/ 07 июля 2011

Никогда не существует единственного решения этой проблемы.Вот XPATH, который, кажется, делает что-то вроде этого:

        HtmlAgilityPack.HtmlDocument doc = new HtmlAgilityPack.HtmlDocument();
        doc.Load(yourHtmlFile);

        doc.Save(Console.Out);

        foreach (HtmlNode node in doc.DocumentNode.SelectNodes("//tr[td/strong/text() = 'Contact']/following-sibling::tr/td/text()[. != '&nbsp;']"))
        {
            Console.WriteLine(node.OuterHtml);
        }

отобразит это:

John Doe
Jane Doe
32
1998
...