Rustでお手軽スクレイピング 2020年夏
はじめに
この記事はRustを用いたスクレイピングを推奨するものではありません。
詳しくは Webスクレイピングの注意事項一覧 を参考にしていただければ幸いです。
本題
お手軽スクレイピング 1 という内容が各言語で実装されているので、Rustで実装していきたいと思います。
Rustでのスクレイピング用途において、HTMLパーサーライブラリは scraper
や select.rs
や kuchiki
がよく使われています。
HTTPクライアントではほぼ reqwest
が使われています。
かなりの少数派ですが、ureq
, surf
や isahc
を使う方もいらっしゃいます。
個人的にはreqwestとscraperを使うので、そちらで実装していきたいと思います。
(ちなみにscraperは更新が滞っていて、メンテナーを募集しているそうです。Looking for maintainer(s) · Issue #36 · causal-agent/scraper)
今回はRust言語の公式ブログ The Rust Programming Language Blog の記事一覧(2021/02/13時点)を降順で取得、表示したいと思います。
実行環境
コード
ライブラリ名を明示的にするために今回はインポートしていませんが、scraper
では use scraper::{Selector, Html};
がよく使われています。
HTTP通信ライブラリ reqwest
は実装を簡素にするため、同期版を使用しています。
fn main() -> Result<(), Box<dyn std::error::Error>> {
// セレクターをパース (このセレクターは記事のアンカーノード群(タイトル)を指す。 <a href="link">Title</a>)
let selector = scraper::Selector::parse("td.bn > a").unwrap();
// `https://blog.rust-lang.org/` へHTTPリクエスト
let body = reqwest::blocking::get("https://blog.rust-lang.org/")?.text()?;
// HTMLをパース
let document = scraper::Html::parse_document(&body);
// セレクターを用いて要素を取得
let elements = document.select(&selector);
// 全記事名を出力
elements.for_each(|e| println!("{}", e.text().next().unwrap()));
// 一件目の記事名
// assert_eq!(elements.next().unwrap().text().next().unwrap(), "Announcing Rust 1.50.0");
// 二件目の記事名
// assert_eq!(elements.next().unwrap().text().next().unwrap(), "mdBook security advisory");
// 三件目の記事名
// assert_eq!(elements.next().unwrap().text().next().unwrap(), "Announcing Rust 1.49.0");
// 最古の記事名
// assert_eq!(elements.last().unwrap().text().next().unwrap(), "Road to Rust 1.0");
Ok(())
}
出力結果は全記事数が多いので11件目以降は省略しています。
$ cargo run
Compiling rust-blog-title-scraper v0.1.1 (/Users/someone/Desktop/rust-blog-title-scraper)
Finished dev [unoptimized + debuginfo] target(s) in 11.77s
Running `target/debug/rust-blog-title-scraper`
Announcing Rust 1.50.0
mdBook security advisory
Announcing Rust 1.49.0
Rust Survey 2020 Results
Next steps for the Foundation Conversation
Launching the Lock Poisoning Survey
The Foundation Conversation
Announcing Rustup 1.23.0
Announcing Rust 1.48.0
Marking issues as regressions
...
手順はコメントをご参照ください。
クセのあるポイントはセレクターを事前にパースしなければいけないことと、 e.text()
の箇所で返ってくる値が単純なテキストではなく、イテレーターを実装したテキストノード群(型)であることです。(他にもクセがあります。)
まとめ
Python, Node.js, Rubyなどのスクレイピングを得意とする言語よりはそこそこに実装疲労度が高いです。 (逆に言うと細かい粒度で様々なクレートを組み合わせることが出来ますので、柔軟度が高いです。)
ただ、今回の様な簡単なスクレイピングであれば簡単に出来ます。
タイトルにお手軽スクレイピングとありますがRustの場合、難しいことをしようとすればする程ドキュメントの熟読が必要になるかと思われますので、うまく判断してご利用ください。
知識や記述の間違いがあればご指摘いただけれると嬉しいです。
Author And Source
この問題について(Rustでお手軽スクレイピング 2020年夏), 我々は、より多くの情報をここで見つけました https://qiita.com/YoshiTheQiita/items/f66828d61293c75a4585著者帰属:元の著者の情報は、元のURLに含まれています。著作権は原作者に属する。
Content is automatically searched and collected through network algorithms . If there is a violation . Please contact us . We will adjust (correct author information ,or delete content ) as soon as possible .