より広範囲のスクレイピングを考えるならば、ログインなどの自動化は必須です。
とはいえ、chromiumとSeleniumの組み合わせは心理的なハードルが高いし、どうしようかなと悩んでいたところ、ふとしたきっかけでfirefoxにもmarionetteという自動操作のフレームワークがあることを知りました。
今回はこのfirefoxのmarionetteを使って、より高度なブラウザの操作を試みてみたいと思います。
まず、marionetteですが、前述の通りfirefoxを操作する為のフレームワークです。
marionetteを有効にすると、firefoxは2828番ポートで待ち受け、操作の為のコマンドを受け付けるようになります。クライアントは、このポートにコマンドを送り、ブラウザを操作します。
firefoxの開発者がブラウザのテストに利用しているとのことですので、廃れることはなさそうな雰囲気です。
ちなみに、Seleniumからもfirefoxを操作できますが、これはfirefoxのWebドライバであるGeckodriverが内部でmarionetteのコマンドに置き換えてfirefoxに送っています。
つまり、firefoxを操作する為だけにSeleniumを導入するなら、直接marionetteを叩いたほうがリーズナブルです。
mozillaから、marionetteを操作するための謹製Webドライバ(marionette_driver)が提供されています。
これを使ってpythonでmarionetteを制御してみたいと思います。
まず、はじめにfirefoxのインストールから、
FreeBSDでは、pkgを使って以下のようにインストールします。
pkg install firefox
次に、pythonがインストールされていなければ、pythonをインストールします。
私の環境だけかもしれませんが、marionette_driverはpython 2.7でないとうまく動きませんでした。
pkg install python27
次に、marionette_driverをインストールするために、pythonのパッケージ管理システムであるpipをインストールします。
pkg install py27-pip
最後に、pipを利用してmarionette_driverをインストールします。
pip-2.7 install marionette_driver
これで環境の構築は完了です。
インストールが完了したら、早速marionetteを試してみたいと思います。
まずは、marionetteを有効にしてfirefoxを起動します。
firefox -private -marionette -p "default" &
Xがない環境では、ヘッドレスモードで起動します。
firefox -headless -private -marionette -p "default" &
これでmarionetteが有効になり、2828番ポートでコマンドを受け付けるようになります。
marionette_driverのAPIリファレンスは以下の場所にあります。
https://firefox-source-docs.mozilla.org/python/marionette_driver.html
それほど大きいものではないですし、直感的に理解できるようにAPIが切られているので、私のようなpython初心者でもなんとかなるのではないかと思います。
とはいいつつも、すぐに試したい人のために、自作の自動ログインとDOM表示のサンプルコードをつけておきます。
自動ログインの方は、ログインするページのHTMLソースを見て、ログインIDとパスワードに割り当てられたnameを確認した上で適宜修正してください。
自動ログイン用スクリプト
import sys
from marionette_driver.marionette import Marionette
from marionette_driver.legacy_actions import Actions
from marionette_driver.errors import NoSuchElementException
gURL="https://www.kishiro.com/login/"
gID="id"
gPassword="password"
def findHTMLElement(aHTMLElements,aAttribute):
tResult=None
for tHTMLElement in aHTMLElements:
if tHTMLElement.get_attribute("name")==aAttribute:
tResult=tHTMLElement
break
return tResult
tCurrentBrowser=Marionette('localhost',port=2828)
tCurrentBrowser.start_session()
tCurrentBrowser.navigate(gURL)
try:
tElements=tCurrentBrowser.find_elements("tag name","input")
except NoSuchElementException:
tElements=None
if tElements is not None:
tElementID=findHTMLElement(tElements,"id")
tElementPassword=findHTMLElement(tElements,"password")
tElementSubmit=findHTMLElement(tElements,"submit")
tElementID.send_keys(gID)
tElementPassword.send_keys(gPassword)
tAsction=Actions(tCurrentBrowser)
tAsction.click(tElementSubmit).wait(2)
tAsction.perform()
tCurrentBrowser.delete_session()
from marionette_driver.marionette import Marionette
from marionette_driver.legacy_actions import Actions
from marionette_driver.errors import NoSuchElementException
gURL="https://www.kishiro.com/login/"
gID="id"
gPassword="password"
def findHTMLElement(aHTMLElements,aAttribute):
tResult=None
for tHTMLElement in aHTMLElements:
if tHTMLElement.get_attribute("name")==aAttribute:
tResult=tHTMLElement
break
return tResult
tCurrentBrowser=Marionette('localhost',port=2828)
tCurrentBrowser.start_session()
tCurrentBrowser.navigate(gURL)
try:
tElements=tCurrentBrowser.find_elements("tag name","input")
except NoSuchElementException:
tElements=None
if tElements is not None:
tElementID=findHTMLElement(tElements,"id")
tElementPassword=findHTMLElement(tElements,"password")
tElementSubmit=findHTMLElement(tElements,"submit")
tElementID.send_keys(gID)
tElementPassword.send_keys(gPassword)
tAsction=Actions(tCurrentBrowser)
tAsction.click(tElementSubmit).wait(2)
tAsction.perform()
tCurrentBrowser.delete_session()
DOM取得用スクリプト
import sys
from marionette_driver.marionette import Marionette
from marionette_driver.legacy_actions import Actions
gURL="https://www.kishiro.com/content/"
tCurrentBrowser=Marionette('localhost',port=2828)
tCurrentBrowser.start_session()
tCurrentBrowser.navigate(gURL)
print(tCurrentBrowser.page_source.encode('utf_8'))
tCurrentBrowser.delete_session()
from marionette_driver.marionette import Marionette
from marionette_driver.legacy_actions import Actions
gURL="https://www.kishiro.com/content/"
tCurrentBrowser=Marionette('localhost',port=2828)
tCurrentBrowser.start_session()
tCurrentBrowser.navigate(gURL)
print(tCurrentBrowser.page_source.encode('utf_8'))
tCurrentBrowser.delete_session()
「python2.7 sample.py」みたいな感じで1つ目のスクリプトを実行した後、2つ目のスクリプトを実行すると、ログイン後のページを取得できると思います。
0 件のコメント:
コメントを投稿