データナード

機械学習と自然言語処理についての備忘録 (旧ナード戦隊データマン)

お知らせ: githubとブログ内容について

これまで記事内でgithubページへのリンクを載せましたが、いくつかのリポジトリを非公開にします。

sugiyamath · GitHub

基本的には、以下の種類のプロジェクトをprivateに変更しました:

  • 実験のために作成したもの。(keras-laser等)
  • ほとんど役に立たず、ゴミ以下のもの。

ブログの方針を変更し、コード自体はブログ内に載せず、一つのgithubリポジトリにまとめます。備忘録的として書く、という方針はそのままにしますが、投稿頻度を週一以下にします。

それと、個人的にATPに興味を持ったので、しばらくはそれに関連することを中心に投稿します。 

ATPに関しては、私の実際の職務等とは一切無関係の単なる趣味です。

以上、よろしくおねがいします。

スクレイピングの13の手法

スクレイピングに関するいくつかの経験則をまとめました。特定のプログラミング言語に依存する話は少なくしてあります。

スクレイピングの困難点

1. ターゲットサイトのhtml構造に依存する。

ターゲットサイトのhtml構造に併せてターゲットコンテンツを抽出する場合、その構造が変わった場合にスクレイパーを修正する必要があります。

2. スクレイピングの効率を上げるとDoS攻撃的な挙動になる。

スクレイピングのとき、並列かつ繰り返し同じサイトにアクセスすることによってDoS攻撃的になってしまうことがあります。

3. ターゲットサイトからのブロックの回避。

目的のサイトからコンテンツを抽出しようとしますが、異常な挙動を検出されてブロックされることがあります。

4. 法的な問題の回避。

スクレイピングに関する法的な問題に関して回避することも一つの課題です。

5. 継続的かつ自動的に収集すること。

スクレイパーを継続運用することが要件にある場合、上記のすべてが問題になります。

経験則一覧

1. 生のhtmlをそのままダウンロードする。

htmlをそのままダウンロードして保存しておく。 次に、ダウンロードした後のhtml等に対して、独立に当該コンテンツの抽出スクリプトをローカルで回す。これにより、データをダウンロードするときにhtml構造を考えなくても良くなり、継続収集がしやすい。

2. htmlパーサより正規表現

htmlパーサを使わずに正規表現を使ったほうが高速な場合が多い。特に、URLの構造はhtmlの構造よりも変わりにくいため、URLを抽出するための正規表現を書いたほうが継続的にスクレイピングしやすい。ちなみに、html内のURLの中で利用するものは、基本的に絶対URLに変換することが多い。

3. ツールの使い分け

cookiejavascriptなどを要求する「難しい」サイトは、chromedriverを使うと成功率が上がる。 「易しい」サイトは、requestsやcurlなど軽量なものを使ったほうが効率がいい。

4. コンテンツ抽出の機械学習モデル

当該コンテンツ部分を抽出する機械学習モデルを作る方法がある。domextractというツールで作成した。 ただし、ヒューリスティックであるという点と、html構造に関して時代の影響を受ける (訓練データが)。

GitHub - sugiyamath/domextract: DOM based web content extractor for Japanese websites

5. VPNやtorを使う

tor (The onion routing) のような無料のオープンソースp2pプロキシを使えば、ブロックの回避がしやすくなる。(数千程度のエンドノードが使える。) ただし、善意の人が立ち上げているサーバであり、乱用は禁物。代わりにVPNを使う方法もある。

nordvpn.com

6. ブロック回避のための小技

  • ダウンロード速度を下げる。
  • 挙動にランダム性を含ませる。
  • UAを工夫する。 
  • cookieやjavascripを必要に応じて使う。

Note: cookiejavascriptを使う必要がある場合、UAをランダムに変えると不審なため、ブラウザ内のデータを消して、IPも変えてからUAを変えたほうが良い。あるいは一般に、統計的に不自然さのないrequest headerを送ることを考慮する。

7. 収集パターン

f:id:mathgeekjp:20200706093238j:plain

ターゲットサイトからのスクレイピングは以下の構成になることが多い:

  • 対象コンテンツを検索する機能。
  • 検索したものからコンテンツのURLを抽出する機能。
  • 抽出したURLからhtml等をダウンロードする機能。
  • ダウンロードした生html等から必要な部分を抽出する機能。

この部分をどう組み合わせるかは複数の戦略がある。

  • それぞれの機能が次の機能へ出力を渡すパイプ・フィルターの方法。
  • それぞれの機能が出力をデータとして保存しておき、それらを非同期に参照する方法。
  • すべての機能を統合してシーケンシャルに実行する方法。

など。

「現在、大量のデータがサイトにはあり、定期的に新しいコンテンツが配信される」というサイトの場合、最初の段階ですべてのデータを取得するクローラを書き、それらの取得が終わった段階で、配信間隔と量に合わせて取得する、というパターンが多い。

8. 正しいリクエス

ログインを要求するサイト、あるいは何らかのPOST, GETクエリの送信を要求される場合、正しいデータを送るように考慮する。

9. 既存スクレイピングツール

ターゲットサイトに対する高機能なスクレイピングツールがある場合、そのツールがブロック回避などに対処していることがあり、そのツールを使ったほうが手間が減る。(twitterscraper, youtube-dl, 等)

10. アクセス時の小技

基本的にリトライ回数を制限して、それを超えたらスキップする。無限にリトライすると、収集の継続性が下がる。

11. ブラウザの管理

chromedriverなどヘッドレスブラウザを使う場合、確率的にブラウザに問題が生じることがあるため、ブラウザをリセット・再起動する機能をつけておくと継続性が上がりやすい。あるいは、ドライバを管理するためのクラスを作って統合する。

12. 非エンジニアが自分で収集したい場合

非エンジニアが使う場合にportiaのようなGUIツールを使うことを検討できる。scrapinghubはノウハウがまとまっているが、柔軟性が低く、有料で、scrapyも柔軟性が低い。フレームワークを使わずに収集することに慣れてしまった開発者にとっては役立つことが少ないが、非エンジニアには有効。

www.scrapinghub.com

13. 自動抽出のためのツール

diffbotは「コンテンツのタイプを判定」「タイプに応じて情報抽出モデルを適用」という2つの段階によってタイプごとのコンテンツを構造的に自動抽出できる。

www.diffbot.com