はじめに:
普段スクレイピング作業を行う際にSeleniumを利用しておりましたが、requestsを使っても同じようなことができないのかな、とふと気になったので試してみました。
なお、以下の記事の内容はChatGPTを使って作成しました。
https://chat.openai.com/share/3d2cd98a-26ea-49d2-b166-3913230053e5
環境
mac 13.4.1
Python 3.10.0
実際の手順
1. Flaskを使用したテスト用Webサイトの作成
既存のWebサイトに直接スクレイピングを行うのは気が引けたので、Flaskを使用してログイン機能を持つWebサイトを作成します。
ログイン後には、ユーザーによる任意の入力を受け付け、特定の入力に対して異なるレスポンスを返すようにします。
from flask import Flask, request, render_template, redirect, url_for
from flask_login import LoginManager, UserMixin, login_user, login_required, logout_user
app = Flask(__name__)
# flask_loginの設定
app.config['SECRET_KEY'] = 'your_secret_key'
login_manager = LoginManager()
login_manager.init_app(app)
login_manager.login_view = "login"
# ユーザー情報のハードコーディング
# 実際の環境ではDB等を使用して保存・取得します。
users = {"admin": {"password": "password"}}
class User(UserMixin):
def __init__(self, id, active=True):
self.id = id
self.active = active
def is_active(self):
return self.active
@login_manager.user_loader
def load_user(user_id):
return User(user_id)
@app.route('/')
@login_required
def home():
return render_template('index.html')
@app.route('/login', methods=['GET', 'POST'])
def login():
if request.method == 'POST':
user_id = request.form.get('user_id')
password = request.form.get('password')
if user_id in users and users[user_id]['password'] == password:
user = User(user_id)
login_user(user)
return redirect(url_for('home'))
else:
return "Invalid user_id or password"
else:
return render_template('login.html')
@app.route('/logout')
@login_required
def logout():
logout_user()
return redirect(url_for('login'))
@app.route('/page', methods=['POST'])
@login_required
def page():
input_value = request.form.get('input_value')
if input_value == '1':
return 'This Page is 1'
elif input_value == '2':
return 'This Page is 2'
else:
return 'Invalid value'
if __name__ == "__main__":
app.run(debug=True)
<!DOCTYPE html>
<html>
<body>
<h1>Welcome!</h1>
<form action="/logout" method="post">
<input type="submit" value="Logout">
</form>
<form action="/page" method="post">
<input type="text" id="input_value" name="input_value">
<input type="submit" value="Submit">
</form>
</body>
</html>
<!DOCTYPE html>
<html>
<body>
<form method="post">
<label for="user_id">User ID:</label><br>
<input type="text" id="user_id" name="user_id"><br>
<label for="password">Password:</label><br>
<input type="password" id="password" name="password"><br>
<input type="submit" value="Submit">
</form>
</body>
</html>
2. Python requestsを使用したWebサイトの自動操作
次に、Pythonのrequests
ライブラリを使用して、作成したWebサイトにログインし、入力を自動化する方法を解説します。ログインと入力の送信は、POSTリクエストを送信することで実現します。
import requests
# FlaskアプリのURLを指定します
url = 'http://localhost:5000'
# ログインページへのリクエストを作成します
s = requests.session()
login_payload = {
'user_id': 'admin',
'password': 'password'
}
# ログインのPOSTリクエストを送信します
login_req = s.post(url + '/login', data=login_payload)
if login_req.status_code == 200:
print('Successfully logged in.')
else:
print('Failed to log in.')
# 新しく追加されたフォームへの値の送信を行います
form_payload = {
'input_value': '1' # 1または2を送信します
}
form_req = s.post(url + '/page', data=form_payload) # 'page'という新しいエンドポイントにPOSTリクエストを送信します
if form_req.status_code == 200:
print('Successfully submitted the form.')
print('Response:', form_req.text) # サーバからのレスポンスを表示します
else:
print('Failed to submit the form.')
3. 実行結果
form_payload = {
'input_value': '1' # 1または2を送信します
}
上記valueで1を入力すると以下のように返される(2を入力すると2が返される)
form_payload = {
'input_value': '3' # 1または2を送信します
}
終わりに
実際のWebサイトでは他にも考慮すべきことはあるとは思いますが、一旦seleniumを使わずにログイン状態の維持等ができることがわかりました。
気が向いたらこれをベースにJSによる動的なWebサイトの操作やWebサイト上のデータのダウンロードなどができるか試してみたいです。