最近、フリーランス向けのスクレイピングプログラムを作ってみました。こんなの欲しいなあという軽い感じで作ったものですが、案外使いやすかったので、ココナラに出品して見ました。
現時点ではクラウドワークスとランサーズを対象として、クローリングとスクレイピングを行うツールですが、今後はサーバにデプロイし定時実行できるようにすることも計画しています。beautifulsoupやseleniumについては一通り使い方は知ってはいたのですが、本格的に作る中で勉強になったことが多々あったので、今回はそれをまとめようと思います。参考サイトの紹介が中心になっているものもあります。
利用環境は以下になります。
- OS: Mac OS X
- エディタ: pycharm community Eddition
- python: 3.7.0
- 各パッケージのバージョン
- selenium: 3.141.0
- beautifulsoup4: 4.7.1
1. Selenium
まずは、JavaScriptが使われたサイトのスクレイピングに必須のSleniumについてです。ブラウザはGoogle Chromeを使っています。
1-1. Seleniumでの待機方法
JavaScriptで書かれたサイトではページを完全に展開するのに時間がかかることがあります。ページのロードが完了していないにも関わらずhtmlデータを取得してしまうと、欲しい情報を取得できなかったり、プログラムの挙動や実行結果が不安定になってしまいます。そのため、ページのロードなどのJavaScriptの起動が完了するのを待つ必要があります。待機の方法は3つです。
- 明示的な待機を指すseleniumの
webDriverWait
メソッド - 暗黙的な待機であるseleniumの
implicity_wait
メソッド - timeモジュールの
sleep
メソッド
明示的な待機は、ある条件(指定したIDを持つhtml要素が現れる)を満たすまでプログラムの実行を止まらせるために使用されます。一方で、暗示的な待機は、webdriverが使用されるたびに一定時間プログラムを待機させるもので、汎用的なものです。ただし、私も色々と使用してみましたが、意図に沿わない場面もあり、少し使いこなすのが難しい印象を受けました。そういったときは素直にtime.sleepを使うと良いようです。具体的な実装方法や使い方については下記のサイトが参考になるので、そちらを確認ください。
- 5. Waits – selenium公式ドキュメント
- PythonでWebスクレイピングする時の知見をまとめておく
- seleniumの2つの待機方法
- 【Python】Selenium では Sleep は使わずに Wait する
1-2. find_element_byによる要素の検索
sleniumで非常に便利だなと思ったのが、find_element_by_
メソッドです。seleniumのdriver.get(url)で指定したページを訪れたあと、このメソッドを使うことで、取得したい要素を簡単に見つけてくれます。このメソッドの使い勝手をよくしていることの一つが、色々な指定の仕方が実装されていることで、find_element_by_class_name
やfind_element_by_css_selector
以外にも、Xpathやid、name、tag_nameなど色々と指定する方法があります。今回、わたしは以下のような使い方をしました。
driver.find_element_by_css_selector('#filter_hide_expired').click()
これは、driver.get
でページロード後、cssセレクタを使ってチェックボタンになっている要素を探し出し、それをクリックするプログラムです。find_element_by
メソッドがあるおかげで1行でこれを実行できるので非常に便利でした。公式サイトのリンクはこちらになります。
1-3. User-Agent(UA)の設定
User-Agentはクローラーを稼働させる上で重要な設定の一つです。User-Agentがデフォルトのせいで、Permisshon Deniedを表す403のステータスコードが返ってきてしまうサイトもあったりします。また、クローリングではマナー上、連絡先を明記することも推奨されており、そういった場合に書き込まれる設定項目でもあります。driverでのUser-Agentの設定は以下のように行います。
options = ChromeOptions()
options.add_argument("--headless")
options.add_argument('--user-agent=hogehoge') #User-Agentの設定
driver = Chrome(path, options=options)
Chromeなどでサイトを見ているときのUser-Agentを確認するには下記のサイトが参考になります。
参考サイトは以下になります。
- headless chromeをPythonのseleniumから動かして引数を考えた (Ubuntu 16.04)
- PythonでWebスクレイピングする時の知見をまとめておく
- UserAgentからOS/ブラウザなどの調べかたのまとめ
2. requests
続いてもスクレイピングで頻繁に使われるrequestsパッケージについてです。これについては、seleniumで説明したUser-Agentをrequestsで設定する方法についてです。以下のようにオプションで渡してあげるだけです。
headers = {"User-Agent":<user agent>}
requests.get(<url>, headers=headers)
これで設定ができています。
3. そのほかのTips
ここからは、小さめのTipsをまとめています。
3-1. open関数のmode=”x”
ファイルを読み込み、ファイルオブジェクトを生成するときにopen関数を使いますが、このときmodeを設定します。一般的には”r”, “w”, “a”がよく使われると思いますが、”x”も設定することができます。これは、ファイルが存在しない場合にだけ新しいファイルが作られ、そうでない場合はエラーが発生するという排他的生成を行う設定です。”w”だと上書きされてしまうが、”a”だとファイルが存在しない場合にえらーになるし…という場合にtry文との組み合わせで使えるのかなと思います。
3-2. ホームディレクトリのパスの取得方法
ホームディレクトリのパスが実は簡単に取得できることがわかりました!!
import os
home_path = os.environ['HOME']
4. まとめ
以上が今回の記事内容になります。もう少し色々な発見があったのですが、よくよく考えると書くほどでないなと思い、こんな感じの記事になりました。今、seleniumを使ったプログラムをサーバにデプロイする方法を模索しているところですので、うまくいったらまた記事にしたいと思います。ちなみに、pythonでのスクレイピングについての記事なら、以下の2つの記事が最強じゃないかと思うので、参考にして頂ければと思います。
読んでいただき、ありがとうございました。