1
7

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

Seleniumを使用しないスクレイピング

Last updated at Posted at 2023-07-27

はじめに:

普段スクレイピング作業を行う際に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サイトを作成します。
ログイン後には、ユーザーによる任意の入力を受け付け、特定の入力に対して異なるレスポンスを返すようにします。

app.py
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)
index.html
<!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>
login.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リクエストを送信することで実現します。

bot.py
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. 実行結果

bot.py
form_payload = {
    'input_value': '1'  # 1または2を送信します
}

上記valueで1を入力すると以下のように返される(2を入力すると2が返される)
スクリーンショット 2023-07-27 12.03.14.png

bot.py
form_payload = {
    'input_value': '3'  # 1または2を送信します
}

そのほかの値を入力すると以下のようになる
スクリーンショット 2023-07-27 12.04.01.png

終わりに

実際のWebサイトでは他にも考慮すべきことはあるとは思いますが、一旦seleniumを使わずにログイン状態の維持等ができることがわかりました。

気が向いたらこれをベースにJSによる動的なWebサイトの操作やWebサイト上のデータのダウンロードなどができるか試してみたいです。

1
7
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
7

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?