使用LINQ解析HTML

3
我正在尝试使用Html Agility Pack和LINQ从HTML表中获取所有单元格。我已经在HtmlAgilityPack.HtmlDocument中加载了HTML源代码,并使用LINQ选择了td标签。但是,在使用foreach迭代结果后,它会在第二个记录处崩溃。
这是HTML源代码的片段:
<tr>
    <td class='city'>New York</td>
    <td>Card 1</td>
</tr>
<tr>
    <td class='city'>London</td>
    <td>Card 2</td>
</tr>
<tr>
    <td class='city'>Tokyo</td>
    <td>Card 3</td>
</tr>
<tr>
    <td class='city'>Berlin</td>
    <td>Card 4</td>
</tr>

这是我制作的内容:

htmlDoc.LoadHtml(await msgRecived.Content.ReadAsStringAsync());

var tds=
    from td in htmlDoc.DocumentNode.Descendants("td")
    where td.Attributes["class"].Value == "city"
    select td.InnerText;

foreach (var td in tds)
{
    citiesText = citiesText + " " + td;
}

它只返回第一个元素,例如如果我使用foreach而不是:
citiesText = tds.ElementAt(0);

它返回New York,但是如果我尝试使用ElementAt(1),则会崩溃并显示对象引用未设置为对象实例。 有什么帮助吗?谢谢。
2个回答

4
你需要确保Attributes["class"]不为null:
var tds =
    from td in doc.DocumentNode.Descendants("td")
    where td.Attributes["class"] != null && td.Attributes["class"].Value == "city"
    select td.InnerText;

第二个检索到的<td>没有class属性,因此在该情况下访问Attributes["class"]会得到null。对null调用.Value导致了异常。或者,您可以使用GetAttributeValue
var tds =
    from td in doc.DocumentNode.Descendants("td")
    where td.GetAttributeValue("class", null) == "city"
    select td.InnerText;

@Nezz:没问题,很高兴能帮忙! - Andrew Whitaker

0
只是猜测,您可能只查看了第一个元素上的td。也许您需要使用htmlDoc.DocumentNode.Descendants("table")。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接