Skip to content

Instantly share code, notes, and snippets.

@fukata
Last active September 5, 2019 17:05
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save fukata/6c2cd216b4c664a3d4e3149aaca266fa to your computer and use it in GitHub Desktop.
Save fukata/6c2cd216b4c664a3d4e3149aaca266fa to your computer and use it in GitHub Desktop.
WebScraper ドキュメント

レシピの書き方

https://scraper.fukata.org

で設定可能なレシピのドキュメントです。

基本構文

recipe:
  - url: "初回アクセスするURL"
    steps:
      - action: "アクション" # 必須
        dom: "対象DOMのCSSセレクタ" # オプション
        key: "結果を格納するキー名" # オプション
        steps: # オプション: アクションによっては更にstepsを記述可能

アクション一覧

: 必須, : 任意, ×: 不可

アクション dom key steps limit value attr skip_data_if_not_found_node skip_click_if_not_found_node transform
get_text × × × × × ×
get_html × × × × × × ×
get_src × × × × × × ×
get_link × × × × × × ×
get_style × × × × × × ×
get_attr × × × × × ×
pagination × x × × × × ×
loop × × × ×
fill_in × × × × × × ×
click × × × × × × ×
go_link × × × × × × ×
go_url × × × × × × ×

transform

取得したデータの形式を変更したり、再フォーマットしたいような場合に使う。

transform一覧

  • translate
    • パラメータ
      • source: 入力元の言語
      • targets: 翻訳言語(複数可)
    • 出力
      • 出力キー名: "{元のkey名}_{target}"
  • format
    • パラメータ
      • input_re: 入力元から文字列を抜き出すための正規表現
      • output: 出力する文字列のフォーマット
    • 出力
      • 出力キー名: "{元のkey名}_format"
  • split
    • パラメータ
      • delimiter: 区切り文字
  • data_type
    • パラメータ
      • type: 変換先の型(現在はarray固定)

サンプルは下記のTipsにあります。

Tips. 一覧と詳細ページの両方をマージした結果を取得したい

ニュースサイトやブログなどを取得する時に一覧から取得したいデータを絞り、各詳細ページの情報をまとめて取得したい場合などに有効。

一覧ページ

<ul class="posts">
  <li class="post">
    <a href="/posts/1">hoge</a>
  </li>
  <li class="post">
    <a href="/posts/2">foo</a>
  </li>
</ul>

詳細ページ

<h1>HOGE</h1>
<div class="content">
  ステキな本文
</div>
<ul class="tags">
  <li><a href="/tags/1">tag1</a></li>
  <li><a href="/tags/2">tag2</a></li>
</ul>

loop , go_link を使うことでこんな感じのレシピを書くことが出来ます。

recipe:
  - url: 'https://example.com'
    steps:
      - action: 'loop'
        dom: 'ul.posts > li'
        key: 'posts'
        steps:
          - action: 'get_link'
            dom: 'a'
            key: 'url'
          - action: 'go_link'
            dom: 'a'
            steps:
              - action: 'get_text'
                dom: 'h1'
                key: 'title'
              - action: 'get_text'
                dom: 'div.content'
                key: 'content'
              - action: 'get_text'
                dom: 'ul.tags > li > a'
                key: 'tags'

こんな感じの結果が返ってくると思います。

{
  "posts": [
    {
      "url": "/posts/1",
      "title": "HOGE",
      "content": "ステキな本文",
      "tags": [
        "tag1",
        "tag2"
      ]
    },
    {
      "url": "/posts/2",
      "title": "FOO",
      "content": "ステキな本文2",
      "tags": [
        "tag3",
        "tag4"
      ]
    },
  ]
}

Tips. ループ対象のDOMの要素を取得したい

<ul class="items">
  <li class="item active">
    <a href="/items/hoge" class="item-link">hoge</a>
  </li>
  <li class="item">
    <a href="/items/foo" class="item-link>foo</a>
  </li>
</ul>

上記のようなHTMLに対して items 以下の liclass 属性も取得したい場合には下記のようなレシピの書き方が出来ます。

recipe:
  - url: 'https://example.com'
    steps:
      - action: 'loop'
        dom: 'ul.items > li.item'
        key: 'items'
        steps:
          - action: 'get_attr'
            dom: '' # domのキー自体なくても良いです。
            key: 'class'
          - action: 'get_link'
            dom: 'a.item-link'
            key: 'url'

これによって下記のような結果を得ることが出来ます。

{
  "posts": [
    {
      "class": "active item",
      "url": "/items/hoge"
    },
    {
      "class": "item",
      "url": "/items/foo"
    }
  ]
}

Tips. ページングに対応したい

<ul class="items">
  <li class="item active">
    <a href="/items/hoge" class="item-link">hoge</a>
  </li>
  <li class="item">
    <a href="/items/foo" class="item-link>foo</a>
  </li>
</ul>

<div class="pagination">
  <ul>
    <li class="prev-link">
      <a href="">前へ</a>
    </li>
    <li class="page-link">
      <a href="">3</a>
    </li>
    <li class="page-link">
      <a href="">4</a>
    </li>
    <li class="page-link">
      <a href="">5</a>
    </li>
    <li class="next-link">
      <a href="">次へ</a>
    </li>
  </ul>
</div>

上記のようなHTMLに対して paginationloop を使うことで下記のように書くことが出来ます。

pagination アクションで指定されている dom が見つからない場合、終端と判断し、処理を中断します。

recipe:
  - url: 'https://example.com'
    steps:
      - action: 'pagination'
        dom: '.pagination > ul > li.next-link > a'
        limit: 10 # 10ページまで
        steps:
          - action: 'loop'
            dom: 'ul.items > li.item'
            key: 'items'
            steps:
              - action: 'get_attr'
                dom: '' # domのキー自体なくても良いです。
                key: 'class'
              - action: 'get_link'
                dom: 'a.item-link'
                key: 'url'

これによって下記のような結果を得ることが出来ます。

{
  "posts": [
    {
      "class": "active item",
      "url": "/items/hoge"
    },
    {
      "class": "item",
      "url": "/items/foo"
    }
  ]
}

transform機能を使ってみる

レシピ

recipe:
  - url: https://blog.fukata.org/archives/9595
  steps:
    - key: title
      dom: '#content h1.entry-title'
      action: get_text
      transform:
        - translate:
            source: ja
            targets:
              - en
              - zh-cn
    - key: entry_date
      dom: '#content .entry-date'
      action: get_text
      transform:
        - format:
            input_re: '([0-9]{4})-([0-9]{2})-([0-9]{2})'
            output: '\1年\2月\3日'

結果

{
  "title": "Windows10でSteamが突然落ちる問題を解決する方法",
  "title_en": "How to solve the problem that Steam suddenly falls on Windows 10",
  "title_zh-cn": "如何解决Steam突然落在Windows 10上的问题",
  "entry_date": "2018-06-20",
  "entry_date_format": "2018年06月20日"
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment