スポンサーリンク

RustでscraperでHTMLクレイピング

Cargo.toml

[package]
name = "htmlgen"
version = "0.1.0"
edition = "2021"

[dependencies]
# HTMLのscraper
# html5ever = "0.26.0"
scraper = "0.15.0"

サンプルコード

fn main() {

    let source:&str = r#"<!DOCTYPE html>
    <html lang="ja">
      <head>
        <title> HTML in the code </title>
      </head>
      <body>
        <div id="mymain">
          <p> first line </p>
          <p> second <br/> line </p>
          <p>
   third
   line
          </p>
          <img src="data.jpg" />
        </div>
        <div id="myfooter">
          <p>copyright</p>
        </div>
      </body>
    </html
    "#;
    //////////////////////////
    // HTMLの解析
    let myparse:scraper::Html = scraper::Html::parse_document(&source);

    let selector:scraper::Selector = scraper::Selector::parse("*").unwrap();

    let parsed:scraper::ElementRef = myparse.select(&selector).next().unwrap();

    println!("*************************");

    traverse_element(&parsed,1);

}



/// @brief 解析済みのHTMLを再帰的に走査して内容を表示
/// @param [in] elementref 解析済みのエレメント
/// @param [in] depth 再帰の階層
/// @return なし 
fn traverse_element(elementref: &scraper::ElementRef, depth: usize) {


    let indent:String = " ".repeat(depth*3);// 階層に合わせて左側に挿入するスペース

    let element:&scraper::node::Element = elementref.value();
    let tag_name:&str = element.name();


    print!("{}",depth); // 階層の表示

    print!("{} {}",indent,tag_name); // タグ名表示

    // 属性取得・保存
    for attr in element.attrs(){
        let attr_name =&attr.0.to_string();
        let attr_value =&attr.1.to_string();
        print!(" {} = {}",
            &attr_name,
            &attr_value
        );

    }
    println!("");


    // 子要素を再帰的に辿る
    for child in elementref.children() {

        if let Some(child_element) = child.value().as_element() {
            // タグの場合

            // 子要素を走査
            let c_elem_ref:scraper::ElementRef = scraper::ElementRef::wrap(child).unwrap();          
            traverse_element(&c_elem_ref, depth + 1);


        } else if let Some(text) = child.value().as_text() {
            // コンテンツの場合
            let contents:&str = text.trim();
            if !contents.is_empty() {
                print!("{}",depth);
                // コンテンツを表示
                println!("[[[[[[[[[[[[[[[[[[{}]]]]]]]]]]]]]]]]]]]]]", contents);
            }
        }
    }

}

実行結果


1    html lang = ja
2       head
3          title
3[[[[[[[[[[[[[[[[[[HTML in the code]]]]]]]]]]]]]]]]]]]]]
2       body
3          div id = mymain
4             p
4[[[[[[[[[[[[[[[[[[first line]]]]]]]]]]]]]]]]]]]]]
4             p
4[[[[[[[[[[[[[[[[[[second]]]]]]]]]]]]]]]]]]]]]
5                br
4[[[[[[[[[[[[[[[[[[line]]]]]]]]]]]]]]]]]]]]]
4             p
4[[[[[[[[[[[[[[[[[[third
   line]]]]]]]]]]]]]]]]]]]]]
4             img src = data.jpg
3          div id = myfooter
4             p
4[[[[[[[[[[[[[[[[[[copyright]]]]]]]]]]]]]]]]]]]]]

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

日本語が含まれない投稿は無視されますのでご注意ください。(スパム対策)


この記事のトラックバックURL: