Rust에서 손쉽게 스크래핑 2020년 여름

소개



이 기사는 Rust를 사용한 스크래핑을 권장하지 않습니다.
자세한 것은 웹 스크래핑 주의사항 목록를 참고해 주시면 감사하겠습니다.

주제



간편한 스크래핑 1이라는 내용이 각 언어로 구현되어 있으므로 Rust로 구현하고 싶습니다.
Rust의 스크래핑 응용 프로그램에서 HTML 파서 라이브러리는 스크래퍼, 세 CT. rs쿠키을 자주 사용합니다.
HTTP 클라이언트는 거의 reqwest를 사용합니다.
상당한 소수파입니다만, ureq , 서핑isahc 를 사용하는 분도 계십니다.

개인적으로는 reqwest와 scraper를 사용하므로 그곳에서 구현하고 싶습니다.
(덧붙여서 scraper는 갱신이 멈추어, 메인테너를 모집하고 있다고 합니다. Looking for maintainer(s) · Issue #36 · causal-agent/scraper )

이번에는 Rust 언어의 공식 블로그The Rust Programming Language Blog 기사 일람(2021/02/13 시점)을 내림차순으로 취득, 표시하고 싶습니다.

실행 환경



  • Rust : 1.50.0 (cb75ad5db 2021-02-10)

  • 스크래퍼 : 0.12.0

  • reqwest ( features = ["blocking"] ): 0.11.0

  • 코드



    라이브러리 이름을 명시적으로 만들기 위해 이번에는 가져오지 않았지만 scraperuse scraper::{Selector, Html};를 자주 사용합니다.
    HTTP 통신 라이브러리reqwest는 구현을 단순화하기 위해 동기 버전을 사용합니다.

    main.rs
    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번째 이후는 생략하고 있습니다.

    stdout
    $ 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() 의 개소에서 돌려주는 값이 단순한 텍스트가 아니고, iterator를 구현한 텍스트 노드군(형)인 것입니다. (그 밖에도 버릇이 있습니다.)

    요약



    Python, Node.js, Ruby 등의 스크래핑을 자랑하는 언어보다는 그곳에 구현 피로도가 높습니다. (반대로 말하면 세세한 입도로 다양한 크레이트를 조합할 수 있으므로 유연성이 높습니다.)
    다만, 이번과 같은 간단한 스크래핑이라면 간단하게 할 수 있습니다.
    타이틀에 간편한 스크래핑이라고 합니다만 Rust의 경우, 어려운 일을 하려고 하면 할수록 문서의 숙독이 필요할까 생각되므로, 잘 판단해 이용해 주세요.

    지식이나 기술의 실수가 있으면 지적해 주시면 기쁩니다.


  • Node.js에서 손쉽게 스크래핑 2020년 여름
  • C#에서 손쉽게 스크래핑 2020년 여름보다 조금 미래

  • 좋은 웹페이지 즐겨찾기