RustでスクレイピングとWebサーバーを開発する手順を書いていきます。
# Rustの開発環境構築
$ brew install rustup-init
$ rustup-init
$ exec $SHELL -l
# プロジェクトのディレクトリ作成
$ cargo new scraping_server
$ cd scraping_server
# 外部パッケージのインストール
$ cargo add actix-web reqwest scraper serde_json
インストールしている外部パッケージは以下のものです。
まず、 scraping_server/src/main.rs を以下の内容に書き換えます。
use actix_web::{get, App, HttpResponse, HttpServer, Responder};
#[get("/")]
async fn handler() -> impl Responder {
HttpResponse::Ok().body("test")
}
#[actix_web::main]
async fn main() -> std::io::Result<()> {
HttpServer::new(|| {
App::new()
.service(handler)
})
.bind(("127.0.0.1", 3000))?
.run()
.await
}
その後、以下コマンドを実行して http://localhost:3000 にブラウザでアクセスすると、”test” の文字が表示されます。
# プログラムのビルドと実行
$ cargo run
これで、Webサーバーの起動ができました。
main.rs に以下の実装を追加します。
use actix_web::{get, App, HttpResponse, HttpServer, Responder};
/* パッケージを追加 */
use scraper::{Html, Selector};
/* 関数を追加 */
async fn scraping() -> Vec<String> {
let mut items: Vec<String> = Vec::new();
// HTMLの取得
let url = "https://en.wikipedia.org/wiki/List_of_programming_languages";
let html = reqwest::get(url)
.await
.unwrap()
.text()
.await
.unwrap();
// HTMLのパース
let fragment = Html::parse_fragment(&html);
let selector = Selector::parse(".div-col li").unwrap();
for element in fragment.select(&selector) {
items.push(element.text().collect::<Vec<_>>().join(""));
}
items
}
#[get("/")]
async fn handler() -> impl Responder {
// 追加した関数を使用する
let items: Vec<String> = scraping().await;
let items_json = serde_json::to_string(&items).unwrap();
HttpResponse::Ok().body(items_json)
}
#[actix_web::main]
async fn main() -> std::io::Result<()> {
HttpServer::new(|| {
App::new()
.service(handler)
})
.bind(("127.0.0.1", 3000))?
.run()
.await
}
追加実装の後、 $ cargo run を再実行して http://localhost:3000 にアクセスすると、 Wikipediaのページから取得したプログラミング言語一覧の文字が表示されるようになります。
補足 Rustには他のプログラミング言語にはない概念があり、コードの内容を理解するには公式のドキュメントが参考になります。 とくに所有権とライフタイムの概念を学んでおくとコードが理解しやすくなります。