at backyard

Color my life with the chaos of trouble.

Rustで簡単なスクレイピングコードを書いてみる

UnicodeがEmoji(絵文字)として定義している文字の一覧を取得したかったので、今回もRustを使って取得してみることにした。

取得対象のサイトは下記。

ja.wikipedia.org

ここに一度だけHTTP アクセスをして、一覧 上の Unicode と書かれている箇所のテキストを取得するだけのコード。
簡単なコードではあるが、Rustはまだまだ使い慣れていないので心して書いていく。

cargo new foobar などとしてプロジェクトを作成し、 [dependencies] に下記を記述する。

[dependencies]
reqwest = { version = "0.11", features = ["blocking"] }
scraper = "0.12.0"

reqwest については昨日の記事でも使っている。

shinshin86.hateblo.jp

今回スクレイピングを行う上でHTMLのparseを scraper を使って行っていく。

docs.rs

実際に書いてみたコードが下記。

use scraper::{Html, Selector};

fn fetch_html() -> Result<String, Box<dyn std::error::Error>> {
    let url = "https://ja.wikipedia.org/wiki/Unicode%E3%81%AEEmoji%E3%81%AE%E4%B8%80%E8%A6%A7";
    let body = reqwest::blocking::get(url)?.text()?;

    Ok(body)
}

fn main() {
    let html = fetch_html().unwrap();
    let document = Html::parse_document(&html);
    let selector_str = "table.sortable.wikitable > tbody > tr > td:nth-child(2)";
    let selector = Selector::parse(selector_str).unwrap();

    for element in document.select(&selector) {
        if let Some(unicode) = element.text().next() {
            println!("{}", unicode);
        }
    }
}

"table.sortable.wikitable > tbody > tr > td:nth-child(2)" という形で普通にセレクターを指定できたので思ったよりも狙った箇所が簡単に取得できた。

上記コードを実行すると、コンソール上にUnicodeの一覧が一行ずつ表示される。

ちなみに最初、

    let document = Html::parse_document(&html);

の行を、

    let document = Html::parse_fragment(&html);

と書いてしまっていて思ったように動作しなかった。
まだ scraper の使い方の理解はhello worldレベル。

以上、簡単なサンプルでした。

追記: 上のサンプルの改良版

github.com

上のサンプルを改良して、unicode と関連する絵文字の名前 name を取得できるようにしたものをGitHubにあげた。