【Python】ChromeDriver+selenium4でgoogle自動検索
ちょっと前から始めているアルバイトの関係で、
Python+ChromeDriver+Selenium4でGoogle自動検索をいかに効率的に行うかをいろいろ試行錯誤したので、その際の技術的メモを残しておきます。
動作環境
Windows 11 Home (64bit)
Chrome 113.0.5672.64(Official Build) (64 ビット)
chromedriver 112.0.5615.49
Python 3.11.1
Selenium 4.9
chromedriver起動オプションあれこれ
chromedriver起動時の引数で結構driver挙動を制御できる。
他にもオプションはあると思うが、
今回挙動をいろいろと確かめたものを置いておく。
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
#ChromeOptions設定
options = webdriver.ChromeOptions()
options.add_argument('--blink-settings=imagesEnabled=false') # 画像の非表示
#options.add_argument('--disable-blink-features=AutomationControlled') # navigator.webdriver=false とする設定
#options.add_argument('--disable-browser-side-navigation') # Timed out receiving message from renderer: の修正
#options.add_argument('--disable-dev-shm-usage') # ディスクのメモリスペースを使う
#options.add_argument('--disable-extensions') # すべての拡張機能を無効
options.add_argument('--disable-gpu') # GPUハードウェアアクセラレーションを無効
#options.add_argument('--headless') # ヘッドレスモードで起動
options.add_argument('--ignore-certificate-errors') # SSL認証(この接続ではプライバシーが保護されません)を無効
#options.add_argument('--incognito') # シークレットモードで起動
#options.add_argument('--no-sandbox') # Chromeの保護機能を無効
#options.add_argument('--start-maximized') # 初期のウィンドウサイズを最大化
options.add_argument('--window-size=480,480') # 初期のウィンドウサイズを指定
#options.add_experimental_option('useAutomationExtension', False) # 拡張機能の自動更新を停止
# Chromeは自動テスト ソフトウェア~~ , Devtools listening~~ を非表示
options.add_argument('--disable-logging')
options.add_argument('--log-level=3')
options.add_experimental_option("excludeSwitches", ['enable-automation', 'enable-logging'])
driver = webdriver.Chrome(service=Service(driver_path), options=options)
ポイント
・今回はGoogle検索結果のタイトルとURLのみを収集する目的だったので、画像表示はオフ、ウインドウサイズも最小限の大きさに。
・出来ればヘッドレスモード(検索結果画面非表示)、シークレットモードにしたかったが、後述の位置偽装の関係でオプション指定断念。
・chromedriver起動時に標準出力に表示される
DevTools listening on ws://127.0.0.1:53064/devtools/browser/dc45c1bc-6a84-4a98-88d2-66af7c5df231
「Devtools listening on ws ~~」と、
chromedriverで起動したブラウザに表示される
「chromeは自動テスト ソフトウェアによって制御されています。」
はexcludeSwitchesオプション1つで消すことが出来た。 ['enable-automation', 'enable-logging'] を併記しているところがミソ。
options.add_experimental_option("excludeSwitches", ['enable-automation', 'enable-logging'])
2023/11/27追記
検索場所偽装
緯度経度情報を指定しての検索を実装したいと思っていろいろ調べた結果、
Chromeデベロッパーツールを操作する「execute_cdp_cmd」で実現できた。但し緯度経度情報を指定したあと、ブラウザをリロードする必要があった。
driver = webdriver.Chrome(service=Service(driver_path), options=options)
driver.get(URL)
# 位置情報を偽装して画面リロード
# (ヘッドレスモード、シークレットモードでは偽装できない)
driver.execute_cdp_cmd(
'Browser.grantPermissions',
{
'origin': URL,
'permissions': ['geolocation']
},
)
driver.execute_cdp_cmd(
'Emulation.setGeolocationOverride',
{
'latitude': xxx.xxxxx,
'longitude': xxx.xxxxx,
'accuracy': 100,
},
)
driver.refresh()
time.sleep(REST)
検索結果csv出力
ファイルI/Oの処理時間短縮のために、結果データをある程度辞書リストにため込んで、writerowsで一括出力。リスト内にUTF-8からSJISに変換出来ない文字が含まれていると「cp932 codec can't encode character」が発生するが、変換出来ない文字1つ1つ処理するのも面倒。出力時にUTF-8出力オプションを指定して、いったんUTF-8のままファイルに書き出してから考えることに。
# CSVファイルを作成
with open('Result.csv', 'a', encoding='UTF-8', newline='') as csv_file:
fieldnames = ['url', 'title', 'keyword']
writer = csv.DictWriter(csv_file, fieldnames=fieldnames)
writer.writerows(results)
csv_file.close()
質問、ご指摘等あればお気軽に。