サブノードからHtmlAgilityPackデータを選択する

c# html html-agility-pack linq parsing

質問

私は以下のHTMLコードを解析したいと思います:

<h3 class='bar'>
  <a href='http://anysite.com/index.php?showuser=7195' title='Profile view'>THIS_IS_USERNAME</a>
  &nbsp;
  <a href='http://anysite.com/index.php?showuser=7195&amp;f=' class='__user __id7195' title='Profile view'>
      <img src='http://anysite.com/public/style_images/car/user_popup.png' alt='' />
   </a>
</h3>

ここで必要なのは、ユーザー名(「THIS_IS_USERNAME」)とプロフィールへのリンク(「 http://anysite.com/index.php?showuser=7195 」)を選択することです

次のコードを使用して、最上位のh3ノードを選択できます。

List<HtmlNode> resultSearch = HTMLPage.DocumentNode.Descendants()
                .Where(
                         x => x.Name.Equals("h3")
                         && x.Attributes["class"] != null
                         && x.Attributes["class"].Value.Equals("bar")                         
                      )
                .ToList();

しかし、どのように私は "h3"ノード自体を取得することはできませんが、必要なプロファイルへのユーザー名とリンクを含むこの属性リンクを持つ "h3"内部の "a"?

受け入れられた回答

リンクノードを直接照会することができます。リンクノードのTitle属性を使用するとかなり独特です。

この場合、XPathを使用すると、すべての中間的なヌルチェックを処理するため、おそらく単純になります.Lineqクエリには多くの定数文字列があるため、型セーフと同じです。

var node = HTMLPage.DocumentNode.SelectSingleNode("//hr[@class='Bar']/a[@title='Profile View' and @href");
if (node != null)
{
    string link = node.Attributes["href"].Value;
    string username = node.InnerText;
}

Linq構文を使用して同様のコードを書くことができます。最初にリンクタグを検索し、それからバックトラックを実行してh3の親を探します。そうすれば、中間のヌルをチェックする必要はありません;):

var node = HtmlPage.DocumentNode.Descendants("a")
    .Where(a =>
        a.Ascendants("h3")
            .Any(h3 =>
                h3.Attributes["class"] != null 
                && a.Attributes["class"].Value == "bar"
            )
    )
    .Where(a => 
        a.Attributes["title"] != null 
        && a.Attributes["title"].Value == "Profile View"
        && a.Attributes["href"] != null
    )
    .FirstOrDefault();

if (node != null)
{
    string link = node.Attributes["href"].value;
    string username = node.InnerText;
}

または、 "bar"の最初の<a>子であるその位置を使用できます。

// the call to First() will throw an exception if the h3 isn't found.
// returning an empty HtmlNode will allow you to ignore that

var node = (HtmlPage.DocumentNode.Descendants("h3")
    .FirstOrDefault( h => 
            h3.Attributes["class"] != null 
            && a.Attributes["class"].Value == "bar")
    ) ?? HtmlPage.CreateElement("h3")) 
    .Elements("a").FirstOrDefault();

if (node != null)
{
    string link = node.Attributes["href"].value;
    string username = node.InnerText;
}


ライセンスを受けた: CC-BY-SA with attribution
所属していない Stack Overflow
このKBは合法ですか? はい、理由を学ぶ
ライセンスを受けた: CC-BY-SA with attribution
所属していない Stack Overflow
このKBは合法ですか? はい、理由を学ぶ