#freeze
[[.NET]]
#contents
どうも断片的な記事しかないみたいなので、かき集めたネタをまとめておくわね。
* 取り込み方 [#m436e2db]
ふたつの書き方まで覚えてるわ。
* DocumentNode.SelectNodes [#k3b04211]
string source = "(HTMLソース)";
string xpath = "xpathコード";
string r = "";
HtmlAgilityPack.HtmlDocument html = new HtmlAgilityPack.HtmlDocument();
html.LoadHtml(source);
try
{
var articles = html.DocumentNode.SelectNodes(@xpath)
.Select(a => new
{
Data = a.InnerText
});
foreach (var a in articles)
{
string kg = "\r\n";
string x1 = a.Data + kg;
r += x1;
}
うちでよく使う方法ね。対象のブツが一つでも複数あっても処理次第だから。
* DocumentNode.SelectSingleNode [#fd20d85e]
こちらは、単発のデータでゲットするみたい。たとえば。
HtmlNode doc = html.DocumentNode.SelectSingleNode(@"//title");
Console.WriteLine(doc.InnerText);
タイトルを探し出して取り込む。最初からひとつとわかってる場合は便利よね。
* Xpathの書き方 [#wb3a4485]
ついでにこっちも。今まで見たパターンね。
** 「特定タグの取り込み」 [#i7848b9f]
//a
ページ内部にある、全ての aタグを探すの。
ただ、これだけだと使いにくいのよね。たとえば、こんな感じかしら。
var articles = html.DocumentNode.SelectNodes(@xpath)
.Select(a => new
{
Html = a.InnerText,
Link = a.Attributes["href"].Value.Trim()
});
foreach (var a in articles)
{
string kg = "\r\n";
string x1 = a.Html + "(" + a.Link + ")" + kg;
r += x1;
}
Attributesの意味は属性が近いのかしら。HTMLのAタグにとつて囲い込んだテキストが値であって、リンクの書かれた href は属性情報という事ね。
ちなみに、class=やid=のついた a タグだけ取り込むなら、こう。
//a[@id='honbun']
classでも同じようにして書くと、同ページの中にある id="honbun" つきの a タグを全部取り出せるってわけ。
うちではこれの応用で『小説家になろう』サイトのお気に入り小説更新情報をもらってきているのだけど、これもこんな感じで一行で書けるの。
//div[@class='favnovel_list']//a
ね。
なお、Attributes みたいなやつは他にこんなのもあるらしいわ。
- Name(ノード名)
- ParentNode(親ノード)
- ChildNodes(子ノードのコレクション)→上の複数取り込み等で使う
- InnerText(ノードに含まれるテキスト。ただし今回のAタグみたいに、属性値であるリンクとかクラス情報は含まれない)
- InnerHtml(そのノードに含まれるHTML生データ。含まれる子ノードがあっても全て含めた全部が降られる)
** 全体のつながりを狙った取り込み [#nced0b1b]
/html[1]/body[1]/div[1]...
これは特定タグ狙いでなくツリー構造で追いかけるみたい。
堅実に見えるけど、ページ構造が変わったら容易にデータがとれなくなるのよね。
個人的にはclassやidで追いかけるのをお勧めするかな。
だって、classやidを定義するのは「この情報はなに」って人間に見やすく属性をつけられている場合が多いから。文書構造を変える事はデザイン変更などでよくあるけど、見た目と関係ないclass値は一度決まったら簡単に変わらないと思うのよね。
* トラブルシューティング [#n270b3af]
:''処理中のところで止まっちゃう''。|HtmlAgilityPackのDLLを同じフォルダに置いてないですよね。特にインストールせずに実行ファイルだけコピーした時にやりがちですけど、DLLもちゃんと入れてください。