【Python】Selenium実践的テクニックとハマりやすいことの解決策

※ 当サイトではアフィリエイト広告を利用しています。リンクは広告リンクも含みます。

この記事は約9分で読めます。
広告

Seleniumを使って個人的にハマって解決した方法等ご紹介します。HTMLがあまり詳しくない人が陥りやすいミスなどです。Seleniumの基本的な使い方は省略しています。ある程度使った人が対象の記事です。順次追加していきます。

実行環境
Windows11
Jupiter Notebook
Python 3.9.13
selenium 4.5.0→4.8.2

#browserはwebdriver.Edge('msedgedriver.exe')のようにwebdriverを入れた変数
広告

アプリでGoogle検索を使うのはやめたほうがいいかも

Google検索を使ってGoogleのライバルになるようなアプリは、Google検索を使えないようにしてくるかも。そんなことできるのか具体的にはわかりませんが。
Seleniumを使う対象は気を付けたほうがいいと思います。

Google検索を使うアプリを昔、私も考えたけどやめました。
検索の件で怒られたわけではなく広告の貼り方で警告がきて、検索もよくよく考えたらやめた方がいいなとおもいました。以下ご参考に。

こちらも参考に。おおやけに使うにはGoogle検索でGoogleが用意した画面出さないとダメかなと思います。

Google検索はなぜ無料なのか、この記事も参考にしてください。

実践的テクニック&ハマりやすいことの解決策

動作が不安定

うまくいく時といかないときがある場合、他の作業を同時に行っているとうまくいかないことがある。プログラムを動かしている最中に新しく手動で何かを立ち上げたりしたとき起こる。なのでできるだけ他にパソコンを使わないときに実行する。
またプラウザを1回すべて閉じてから実行するとうまくいく場合がある。メモリの不足が原因と思われる。

ある日、突然おかしくなる

WEBドライバー(Edgeの場合msedgedriver.exeクロームの場合Chromedriver.exe)とプラウザのバージョンがあってない。ブラウザは自動的で更新され続けているので、使用しているWEBドライバがブラウザのバージョンに対応できなくなるとおきます。
msedgedriver.exe、Chromedriver.exeを使っているブラウザに対応したものと入れ替えるだけで直ります。

Classが複数ある場合の指定方法が間違っている場合がある

HTMLに詳しくない人向けです。
class="kore are sore"というようにスペースで単語がつながっているものはclass名が1つではなく複数のclass名を指定している。kore are soreはそれぞれ別のclass名である。
なのでそのまま下のようにコピペしてもエラーにはならないが動かすと別の要素を対象にしてしまうことがある。対策としてスペースを.(ピリオッド)に変える。
それでもうまくいかないときは1つだけにする。

find_element(By.CLASS_NAME,"kore are sore")
→find_element(By.CLASS_NAME,".kore.are.sore")
→find_element(By.CLASS_NAME,"kore")
目次へ

スクロール

サイトによってはurlにアクセスしたらすべて読み込まれないものがあります。そういうサイトは画面表示しない部分は高速化のためスクロールして表示する直前に読み込まれる。なのでプログラムをつくるときにスクロールして要素を確認できても実際の運用でスクロールしないと要素が読み込まれていない。そういうときは以下のようにスクロールしてから実行するとうまくいく。

0,500ピクセルにスクロールする場合
browser.execute_script("window.scrollBy(0, 500);")
#browserはwebdriver.Edge('msedgedriver.exe')のようにwebdriverを入れた変数

paiautoguiを使用する場合(paiautoguiについては後半で解説)
pag.press("pageup")
pag.press("pagedown")
pag.press("home")
pag.press("end")

Javascriptを使う(ElementClickInterceptedException要素が範囲外にあるエラーのとき)

browser.execute_script(Javascriptの命令)でJavaScripが使える。Javascriptを使うほうが範囲外にある要素をクリックできる場合がある。理由はわからないが試す価値はあります。

具体的使用例
browser.execute_script(
                    "document.getElementsByClassName ('クラス名')[0].click();")  

操作しているWindowsの確認

タブをとじたときなど操作ターゲットのページが、変わってしまい操作できなくなる。
現在どのurlが操作対象なのか以下で確認できます。
print(browser.current_url)
#browserはwebdriver.Edge('msedgedriver.exe')のようにwebdriverを入れた変数
ちなみにプラウザを閉じるときは
browser.close()
プラウザ全部を閉じるとき
browser.quit()

新しいタブに操作対象を移動する

クリックして開いた新しいタブを操作する場合。クリックして開いただけでは操作対象は移動していない。ウィンドウハンドルを変更する必要がある。

# ウィンドウハンドル(操作ターゲットのページ一式)を取得する。新しいほど末尾。
handle_array = browser.window_handles
# 新しく開いたページに操作ターゲットが移動する
browser.switch_to.window(handle_array[-1])

違うページに行ってしまったので戻りたいとき

browser.back()で戻れます。
操作ターゲットのページに戻っているかは
print(browser.current_url)で確認できます。
目次へ

要素があるか確認

以下のように要素の長さによって判別できる。

if len(browser.find_elements(By.CLASS_NAME,"abc"))>0:
    要素class名abcがあるときの処理
else:
  要素class名abcがないときの処理

その際find_elementではエラーになるfind_elementsでリストで取得するようにする。要素が存在しない場合、以下のようにリストで取得していれば[]空リストが取得されエラーにはならない。
print(browser.find_elements(By.CLASS_NAME,"abc"))
[]
print(browser.find_element(By.CLASS_NAME,"abc"))
エラーになる。

ヴァージョンアップでワーニング

DeprecationWarning: headless property is deprecated, instead use add_argument(‘–headless’) or add_argument(‘–headless=new’) options.headless = True

selenium4.8.2にバージョンアップしたら見出しのワーニングが出ました。以下の1行変更で直ったと思ったけど、ちょっとおかしい。ワーニングは出ないが動作が不安定になった。
options = Options()
options.add_argument(f’service={chrome_service}’)
# options.headless = True
→options.add_argument(‘–headless’)

browser = webdriver.Chrome(options=options)

結局ワーニングをだしておくかヘッドレスをやめてワーニングを出さないようにするかの2択で今のところやっています。

Seleniumの代わり、または合わせて使用できるもの

タブを閉じる(pyautogui編)

pyautoguiを使えばマウス操作やキー操作が自動化できます。これを使って自動キー操作でタブを閉じる方法です。キー操作ではctrl+wでウィンドウやタブを閉じることができます。その際Jupiter Notebookで実行するときは下の「JupitorNotebookでpyautoguiの使い方の基本」を参照してください。

import pyautogui as pag
pag.hotkey("Ctrl","w")

JupitorNotebookでpyautoguiの使い方の基本

Jupiter Notebookでpyautoguiを実行するとアクティブになっているウィンドウがJupiter NotebookなのでJupiter Notebookに対して操作してしまいます。
Alt+Tabは現在開いているWindowが順番にアクティブになります。
キー操作でALT+Tabをやってみると動作が分かります。
なので操作対象のWindowを直前に表示させ、その後Jupiternotebookに戻って以下をプログラムの先頭に書いたプログラムを実行すれば操作したいWindowがアクティブになります。

import pyautogui as pag
time.sleep(1)#1秒ウェイトtime.sleepはimport timeすれば使える。
pag.hotkey("alt","tab")

Seleniumを使わないでテキストを取得する

単純に全部コピーで処理する方法です。

別タブで開く

Seleniumと関係ありませんが関連テクニックとしてご紹介。

subprocess.Popen([r'Edgeなどのexeファイルがある場所','別タブで開くurl'])

具体例(Edgeで別タブでyahooを開く)
import subprocess
subprocess.Popen([r'C:\Program Files (x86)\Microsoft\Edge\Application\msedge.exe','https://www.yahoo.co.jp/'])

この記事を書いたイチゲを応援する
Vプリカでのお支払いがおすすめです。
MENTAやってます(ichige)

目次へ

コメント

タイトルとURLをコピーしました