LoginSignup
5
10

More than 3 years have passed since last update.

Selenium(Python)で複数サイトを自動ブラウジングするツール作った

Posted at

はじめに

ブラウジングしたいURLが書かれたテキストファイルを受け取り、自動でブラウジングしてくれるツールを作成しました。
こだわった点はyoutubeyahooなど、スクロールするにつれてコンテンツが増えるページにも対応した点です。
参考になれば幸いです。

コード

AutoBrowsing.py
import os
import re
import sys
import time
import chromedriver_binary
import requests
from selenium import webdriver

# *** main関数(実行は最下部) ***
def main():
    # URL一覧ファイルの受付
    input_path = input_urls_file()
    # URLリストをファイルから取得
    url_list = get_url_list(input_path)
    # URLリスト中のURLの検証
    validate_url(url_list)
    # ブラウジング確認の受付
    confirm_browsing()
    # ブラウジング
    browsing_urls(url_list)


# *** URL一覧ファイルの入力を受け付ける関数 ***
def input_urls_file():
    print("\n########## Start processing ##########")
    print("Input filepath of urls : ")
    # ファイルの入力の受付(フルパス)
    input_path = input()
    print("\nCheck input file ...\n")
    # ファイルの存在チェック
    if os.path.exists(input_path):
        print('  [OK]: File exists. : ' + input_path)
    # ファイルが存在しない場合は終了
    else:
        print("  [ERROR]: File doesn't exist! : " + input_path)
        print("\nSystem Exit.\n")
        sys.exit()
    return input_path


# *** URLリストをファイルから取得する関数 ***
def get_url_list(input_path):
    # ファイルのオープン
    targetFile = open(input_path)
    # 行ごとのURLのリスト
    url_list = targetFile.readlines()
    # ファイルのクローズ
    targetFile.close()
    return url_list


# *** URLスキームとステータスコードを検証する関数 ***
def validate_url(url_list):
    print("\nCheck url scheme and status code ...\n")
    # エラーフラグ
    hasError = False
    for url in url_list:
        # Tips:readlines()で読み込んだ1行には改行コードがついてくるので削除
        unsafe_url = url.rstrip()
        # URLのスキームパターン
        URL_PTN = re.compile(r"^(http|https)://")
        # パターンに一致しない場合はエラー
        if not (URL_PTN.match(unsafe_url)):
            print("  [ERROR]: Url isn't valid! : " + unsafe_url)
            hasError = True
            # スキームが正しくない場合にはURLにリクエストしない
            continue
        # スキームが正しい場合にURLにリクエスト
        r = requests.get(unsafe_url)
        # ステータスコードが200(リダイレクトでも200)以外の場合はエラー
        if (r.status_code != 200):
            print("  [ERROR]: Status code isn't 200! : [" +
                  r.status_code + "]:" + unsafe_url)
            hasError = True
    # スキームが正しくない、またはステータスコードが200以外のものがあった場合には終了
    if hasError:
        print("\nSystem Exit.\n")
        sys.exit()
    print("  [OK]: All urls are valid and 200.")
    print("  [OK]: Number of urls : " + str(len(url_list)))


# *** ブラウジング開始の入力を受け付ける関数 ***
def confirm_browsing():
    # Yes/No以外は無限ループ
    while True:
        print("\nStart browsing?  y/n  (default:y)")
        # 入力は全て小文字として受付(比較が楽)
        confirm_cmd = input().lower()
        # デフォルト(Enter)のみでもyとして扱う
        if ((confirm_cmd == "") or (confirm_cmd == "y")):
            break
        elif ((confirm_cmd == "n")):
            print("\nSystem Exit.\n")
            sys.exit()
        else:
            pass


# *** ブラウジングを実行する関数 ***
def browsing_urls(url_list):
    options = webdriver.ChromeOptions()
    # ブラウザを最大化
    options.add_argument("--start-maximized")
    # 「Chromeは自動テストソフトウェアによって制御されています。」を消すためのオプションの指定
    options.add_experimental_option("excludeSwitches", ["enable-automation"])
    options.add_experimental_option('useAutomationExtension', False)
    driver = webdriver.Chrome(options=options)
    print("\n===== start =====")
    # 一行ずつブラウザを開く
    for i, url in enumerate(url_list):
        # URLリスト全体中何個目のURLを表示しているかを出力
        print("  " + str(i+1) + "/" + str(len(url_list)))
        # URLにアクセス
        driver.get(url)
        # ↓各URLに行いたい処理があればここで呼び出す関数を変更する
        # 各URLを最下部までスクロールする処理
        scrolle_to_end(driver)
    print("===== end =====\n")
    # 終了
    driver.quit()
    print("Complete.\n")


# *** ページの最下部までスクロールする関数 ***
def scrolle_to_end(driver):
    # スクロールする速さ(1以上を指定)
    SCROLL_SPEED = 3
    while not is_scrolle_end(driver):
        # 0.5秒待つ(基本的には不要だが読み込みが遅いときなどに使用する)
        # time.sleep(0.5)
        # 相対値でスクロール
        driver.execute_script("window.scrollBy(0, "+str(SCROLL_SPEED)+");")
    # 1秒待つ
    time.sleep(1)


# *** 一番下までスクロールしたか否か判定する関数 ***
def is_scrolle_end(driver):
    # 一番下までスクロールした時の数値を取得(window.innerHeight分(画面表示領域分)はスクロールをしないため引く)
    script = "return " + str(get_page_height(driver)) + \
        " - window.innerHeight;"
    page_most_bottom = driver.execute_script(script)
    # スクロール量を取得(ブラウザの種類やバージョンなどによって取得方法が異なる)
    script = "return window.pageYOffset || document.documentElement.scrollTop;"
    scroll_top = driver.execute_script(script)
    is_end = scroll_top >= page_most_bottom
    return is_end


# *** ページの高さを取得する関数 ***
def get_page_height(driver):
    # ブラウザのバージョンやサイトによって異なるため、最大値を取る
    # https://ja.javascript.info/size-and-scroll-window#ref-633
    # Tips:文字列を改行なしで複数行で書きたい場合には()で囲む
    script = ("return Math.max("
              "document.body.scrollHeight, document.documentElement.scrollHeight,"
              "document.body.offsetHeight, document.documentElement.offsetHeight,"
              "document.body.clientHeight, document.documentElement.clientHeight"
              ");")
    height = driver.execute_script(script)
    return height


# main関数の実行
main()

↓サンプルのインプットファイル

test_url_list.txt
https://www.google.com/
https://qiita.com/
https://www.youtube.com/
https://www.yahoo.co.jp/

↓実行時のコンソール

########## Start processing ##########
Input filepath of urls :
c:\Users\hoge\Desktop\work\python\AutoBrowsing\test_url_list.txt

Check input file ...

  [OK]: File exists. : c:\Users\hoge\Desktop\work\python\AutoBrowsing\test_url_list.txt

Check url scheme and status code ...

  [OK]: All urls are valid and 200.
  [OK]: Number of urls : 4

Start browsing?  y/n  (default:y)



===== start =====
  1/4
  2/4
  3/4
  4/4
===== end =====

Complete.

実行準備

pipでのChromeDriverのインストール時のバージョンの罠

seleniumでChromeを走査する際にpipでインストールを行う場合、単純にpip install chromedriver-binaryコマンドでインストールすると、バージョンの問題で実行時にエラーになります。
インストール時にはバージョンを指定してください。
バージョン指定なしでインストールしてからでも、バージョンを指定してインストールすれば、自動で前のものはアンインストールされます。

※詳細については以下
[selenium向け] ChromeDriverをpipでインストールする方法(パス通し不要、バージョン指定可能)

おわり

今回は自動でブラウザを立ち上げた後、最下部までスクロールするという処理を行いました。
リストを受け付けてそのURLに対して何かしらの処理を行うという処理は使い回せそうなので、他にも何か作ってみようと思います。

5
10
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
5
10