中年プログラマーの息抜き

ブログをはじめました。気の向くままにプログラム関連ネタをメモしていきます。

Pythonでスクレイピング(Selenium,Beautifulsoup,otp)

やりたいこと

pythonスクリプトを実行し、以下の順で自動処理するマクロを作る。

  1. ブラウザ(Chrome)をシークレットモードで開く
  2. amazonショッピングサイトに自分のアカウントでログイン認証
  3. あらかじめ選んでおいた商品をカートに入れる

実行環境

Pythonを使いますが、いくつかライブラリを追加しました。
・chromedriver-binary
selenium
・beautifulsoup4
・oathtool

早速、環境を作りましょう。
といっても、簡単に進めたいので、PIPを使います。

Pythonのバージョン

python --version
Python 3.9.7

PIPのバージョン

pip --version
pip 22.2.2

・・・うーん、では、最新化しておきましょうか。

python -m pip install --upgrade pip
pip --version
pip 23.2

Chromeのバージョン

ブラウザを開いてバージョンを調べますね。・・115.0.5790.99を確認

ライブラリ「chromedriver-binary」を追加

pip install chromedriver-binary==115.*

ERROR: Could not find a version that satisfies the requirement chromedriver-
・・・
112.0.5615.49.0, 113.0.5672.24.0, 113.0.5672.63.0, 114.0.5735.16.0, 114.0.5735.90.0)
ERROR: No matching distribution found for chromedriver-binary==115.*

エラーが出たので、一番近い「114.0.5735.90.0」を追加しましょう。

pip install chromedriver-binary==114.0.5735.90.0
pip list | grep chromedriver-binary
chromedriver-binary 114.0.5735.90.0

ライブラリ「selenium」を追加

pip install selenium
pip list | grep selenium
selenium           4.10.0

ライブラリ「beautifulsoup4」を追加

pip install beautifulsoup4
pip list | grep beautifulsoup4
beautifulsoup4     4.12.2

ライブラリ「oathtool」を追加

pip install oathtool
pip list | grep oathtool
oathtool            2.3.1

pypi.org
ちょっと最終更新が古いですが、Amazonの2段階認証はパスできた。ネット調べるとミドル的なoath-toolkitの情報が多く見つかりますね。(今回のネタでは使いません)

Python+Seleniumで2段階認証(6桁のパスコード)を突破する全手順 | たぬハック

ライブラリ「そのほかすべて」を最新で更新しておこう

pip-reviewを導入します。

pip install pip-review
pip list | grep pip-review
pip-review          1.3.0

 

パスを通します。(設定していなければ追加します)

set path=C:\Users\・・・\AppData\Roaming\Python\Python39\Scripts;%path%

 

まとめて最新で更新してみます。

pip-review --auto

 

私の環境だと依存がらみでエラーになりました。

RROR: pip's dependency resolver does not currently take into account all the packages that are installed. This behaviour is the source of the following dependency conflicts.
fabric3 1.14.post1 requires paramiko<3.0,>=2.0, but you have paramiko 3.2.0 which is incompatible.
html5print 0.1.2 requires ply==3.4, but you have ply 3.11 which is incompatible.

1つずつ調整します。

まずは「ply」と「fabric3」

pip uninstall ply
pip install ply==3.4
pip install -U fabric3

 

続けて「paramiko」と「html5print」

pip uninstall paramiko
pip install paramiko==2.12.0
pip install -U html5print

 

2段階認証アプリ(oathtool)を登録していきます。

アカウント > ログインとセキュリティ > 2段階認証 > 管理ボタンからバックアップ手段を追加(新しい電話または認証アプリを追加)とリンクをたどります。

バーコードをスキャンできませんか? をクリックするとシークレットが表示されるのでこれを控えておき、OTPで利用します。

python -m oathtool "!!! your secret !!!"

999999

↑をワンタイムパスワードに入力して「ワンタイムパスワードを確認して次に進む」と2段階認証アプリ(oathtool)がアカウントに紐づきます。

2段階認証アプリ(oathtool)をソースに組み込む。

こんな感じで組み込めます。

totp = oathtool.generate_otp("!!! your secret !!!")

全体のソース(Python)はこんな感じです。

import time import oathtool from selenium import webdriver def request(url): global driver try: driver.get(url) time.sleep(3) except: pass def click(xpath): global driver try: el1 = driver.find_element(webdriver.common.by.By.XPATH, xpath) el1.click() time.sleep(3) except: pass def input(xpath, text): global driver try: el1 = driver.find_element(webdriver.common.by.By.XPATH, xpath) el1.send_keys(text) except: pass options = webdriver.ChromeOptions() options.add_argument('--incognito') options.add_argument('--headless') driver = webdriver.Chrome(options=options) request('https://www.amazon.co.jp/') click('//*[@id="nav-signin-tooltip"]/a') input('//*[@id="ap_email"]', '!!! your email !!!') click('//*[@id="continue"]') input('//*[@id="ap_password"]', '!!! your password !!!') click('//*[@id="signInSubmit"]') totp = oathtool.generate_otp("!!! your totp secret !!!") input('//*[@id="auth-mfa-otpcode"]', totp) click('//*[@id="auth-signin-button"]') request('https://www.amazon.co.jp/dp/・・・/') click('//*[@id="add-to-cart-button"]') driver.quit()