差分
このページの2つのバージョン間の差分を表示します。
| 両方とも前のリビジョン前のリビジョン次のリビジョン | 前のリビジョン | ||
| selenium-webdriver [2025/01/13 01:59] – skk | selenium-webdriver [2025/11/06 20:33] (現在) – skk | ||
|---|---|---|---|
| 行 1: | 行 1: | ||
| - | = [[selenium-webdriver]] LM: [2025-01-13 01:59:36] | + | = [[selenium-webdriver]] LM: [2025-11-06 20:33:13] |
| ~~NOCACHE~~ | ~~NOCACHE~~ | ||
| 行 42: | 行 42: | ||
| ===== - tips ===== | ===== - tips ===== | ||
| - | ==== - 名前をつけて保存の処理 | + | ==== - 画像保存の方法 |
| [2025-01-13] | [2025-01-13] | ||
| + | |||
| selenium を使って,Web 上の画像を保存する方法は,大きく分けて, | selenium を使って,Web 上の画像を保存する方法は,大きく分けて, | ||
| - screenshot をとる | - screenshot をとる | ||
| - | - 画像の URL を取得し,request.get() する | ||
| - 名前をつけて保存 | - 名前をつけて保存 | ||
| + | - 画像の URL を取得し,request.get() する | ||
| - | の3つな気がする. | + | の3つな気がする.1 番目は表示さえされてれば確実に画像が保存できるのだが,画像が縮小されていると画質が落ちてしまうし,取得した画像を jpeg や webp に変換していると結構な CPU リソースを食ってしまう. |
| + | 2 番目の名前をつけて保存は,もし画像の URL とスクレイピング先のホストが同じ場合,キャッシュから保存されるので,1度の URL アクセスで画像が保存できるのでもっとも効率的になるが,違う場合,クロスサイト対策(?)の関係で,もう一度 URL アクセスが発生してしまう. | ||
| + | |||
| + | そのため,2 番目と 3 番目はアクセスという面で考えると同じになってしまう. | ||
| + | |||
| + | 状況に応じて,適した方法を選ぶ必要がある. | ||
| + | |||
| + | ==== - 名前をつけて保存 ==== | ||
| + | |||
| + | [2025-01-13] | ||
| + | |||
| + | ブラウザ上の画像を右クリックし,名前をつけて保存,と押すと,保存ダイアログが出てきて,保存先を選び,画像を保存することになる. | ||
| + | この時出てくる保存ダイアログは,ブラウザの一部ではなく,OS(Windows)の管理下にあるので,selenium からコントロールすることができない. | ||
| + | よって,名前をつけて保存の処理を自動で行ないたい場合は,selenium とは別の枠組で考える必要がある. | ||
| + | |||
| + | FreeBSD/ | ||
| + | |||
| + | 僕の場合,ウィンドウマネージャを指定せずに,Xvfb に対して seleinum で操作している chromium を表示している状態である. | ||
| + | |||
| + | 次に,selenium において,次のように javascript を利用してブラウザ上での右クリックを行なわせる. | ||
| + | |||
| + | <code python> | ||
| + | driver.execute_script(f""" | ||
| + | const downloadImage = document.createElement(' | ||
| + | | ||
| + | | ||
| + | | ||
| + | | ||
| + | """ | ||
| + | </ | ||
| + | |||
| + | 実行すると,Xvfb 上では名前をつけて保存ダイアログにフォーカスがあたった状態で出てくる. | ||
| + | あとは,保存先ディレクトリを指定し,保存ボタンを押す.xdotool ならば, | ||
| + | |||
| + | <code bash> | ||
| + | % xdotool key Home | ||
| + | % xdotool type / | ||
| + | % xdotool key Return | ||
| + | </ | ||
| + | |||
| + | となる.もしコマンドライン上で実際に動かす場合は,DISPLAY 環境変数も指定しなければならない. | ||
| + | これらのコマンドを python 上でコマンド呼出せばよい.例えば,以下のような形. | ||
| + | |||
| + | <code python> | ||
| + | xdotool = [" | ||
| + | subprocess.run(xdotool) | ||
| + | </ | ||
| ==== - selenium (bot) 検知への対応について ==== | ==== - selenium (bot) 検知への対応について ==== | ||
| 行 60: | 行 107: | ||
| * https:// | * https:// | ||
| * https:// | * https:// | ||
| + | * [2025-02-22] https:// | ||
| === - undetected chromedriver [2023-09-07] === | === - undetected chromedriver [2023-09-07] === | ||
| 行 73: | 行 121: | ||
| FreeBSD で動作させる為には,[[https:// | FreeBSD で動作させる為には,[[https:// | ||
| + | |||
| + | === - seleniumbase [2025-02-22] === | ||
| + | undetected_chromedriver は,2025/ | ||
| + | |||
| + | ZenRow というクラウドサービスを使っても anti-bot の回避はできるようだが月額がまーまー高い.広告記事だと思うけど,この ZenRow の特集記事が良くできているので参考に読むと良い. | ||
| + | |||
| + | 今は,SeleniumBase というツールまたは,nodriver というツールが最近ではアクティブな模様.nodriver は undetected_chromedriver の作者が作っている後継だけど,selenium の書きにくいところと決別したいらしく,結構独自の書き方にしないといけなくて,既存のコードがある場合には導入しにくい.SeleniumBase は undetected_chromedriver を fork して独自進化させてるっぽいので,undetected_chromedriver からの乗り換えにはとても便利. | ||
| + | |||
| + | また,multiprocessing 環境への対応を頑張った形跡が見られるのも嬉しい.undetected_chromedriver は,複数のプロセスを動かそうとすると,Text Busy と言われることがちょいちょいあった.これは,ChromeDriver を利用するたびに chromedriver をダウンロードしてきてパッチを当ててたので,複数プロセスで動かそうとすると,時々競合のような状態になっていたと想像している. | ||
| + | SeleniumBase は,初回起動時に uc_driver という,パッチを当てまくった chromedriver を作成して,以降は必要がなければずっとそれを使い続けるので,複数のプロセスから ChromeDriver(=uc_driver) を利用しても問題が起きない. | ||
| + | |||
| + | さらに,undetected_chromedriver を FreeBSD で無理矢理動かしていた時は,zombie プロセスが大量に作成されてしまったので,定期的にプログラムを再起動してゾンビを殺していたが,終了処理などがきれいになっているのか,SeleniumBase だと zombie が発生しなかった. | ||
| + | |||
| + | ということで,今から利用する場合は,SeleniumBase の方が全然良い.(nodriver ももしかしたら良いのかもしれないけど,試してはいない) | ||
| === - UA について === | === - UA について === | ||
| 行 107: | 行 169: | ||
| ====== - freebsd における tips ====== | ====== - freebsd における tips ====== | ||
| + | ===== - SeleniumBase の動作設定 [2025-02-22] ===== | ||
| + | SeleniumBase もソースコードないでは Linux への分岐しか対応してない.ただ,undetected_chromedriver は Linux バイナリをダウンロードしてきていたので,Linux Emulation しなければならなかったが,SeleniumBase は chromedriver に対してなんらかの方法でパッチを当てているので,FreeBSD でインストールできる Chromium に附属している chromedriver をベースにして動作する.つまり,linux emulation しなくても大丈夫. | ||
| + | |||
| + | [2025-11-06] 8 ヶ月ぶりにバージョンアップしたが,すでにそこそこ変更点があった.特に,OS/ | ||
| + | |||
| + | ==== - python ライブラリの準備 ==== | ||
| + | <code bash> | ||
| + | # pip install seleniumbase | ||
| + | </ | ||
| + | |||
| + | ==== - python ライブラリの FreeBSD 対応 ==== | ||
| + | / | ||
| + | |||
| + | < | ||
| + | __init__.py | ||
| + | __pycache__ | ||
| + | </ | ||
| + | |||
| + | patecher.py で以下. | ||
| + | |||
| + | <code python> | ||
| + | 15c16 | ||
| + | < IS_POSIX = sys.platform.startswith((" | ||
| + | --- | ||
| + | > IS_POSIX = sys.platform.startswith((" | ||
| + | 30c31 | ||
| + | < if sys_plat.endswith(" | ||
| + | --- | ||
| + | > if sys_plat.endswith(" | ||
| + | </ | ||
| + | |||
| + | / | ||
| + | |||
| + | <code python> | ||
| + | 47 def is_linux(): | ||
| + | 48 | ||
| + | </ | ||
| + | |||
| + | [2025-11-06] __init__.py は,以下の行数の部分で,FreeBSD の分岐を追加. | ||
| + | <code python> | ||
| + | 30 IS_POSIX = sys.platform.startswith((" | ||
| + | 481 # (So that close() is always called) | ||
| + | 482 if " | ||
| + | 483 | ||
| + | 533 if " | ||
| + | 534 | ||
| + | 535 if self.service.is_connectable(): | ||
| + | 559 | ||
| + | 560 if " | ||
| + | 561 | ||
| + | </ | ||
| + | |||
| + | [2025-11-06] core/ | ||
| + | |||
| + | <code python> | ||
| + | 34 class OSType(object): | ||
| + | | ||
| + | | ||
| + | | ||
| + | | ||
| + | 39 | ||
| + | 56 def os_name(): | ||
| + | | ||
| + | | ||
| + | | ||
| + | | ||
| + | | ||
| + | | ||
| + | 109 if os_name() != OSType.LINUX or os_name() != OSType.FREEBSD: | ||
| + | 110 | ||
| + | 111 paths = [ | ||
| + | 112 "/ | ||
| + | 434 | ||
| + | 435 | ||
| + | 436 | ||
| + | 437 | ||
| + | 438 | ||
| + | 439 | ||
| + | 440 | ||
| + | 517 | ||
| + | 518 " | ||
| + | 519 " | ||
| + | 520 " | ||
| + | 521 " | ||
| + | 522 " | ||
| + | 523 " | ||
| + | 524 " | ||
| + | 525 " | ||
| + | 526 ), | ||
| + | </ | ||
| + | |||
| + | これで少なくとも,僕の環境では SeleniumBase が FreeBSD で動作している. | ||
| + | |||
| ===== - undetected-chromedriver の動作設定 [2023-09-07] ===== | ===== - undetected-chromedriver の動作設定 [2023-09-07] ===== | ||
| undetected-chromedriver がダウンロードできるバイナリは上述の通りで,FreeBSD で動作させる為には,以下のどちらかの対応かと考えた. | undetected-chromedriver がダウンロードできるバイナリは上述の通りで,FreeBSD で動作させる為には,以下のどちらかの対応かと考えた. | ||
| 行 119: | 行 274: | ||
| ==== - python ライブラリの準備 ==== | ==== - python ライブラリの準備 ==== | ||
| - | < | + | < |
| # pip install undetected-chromedriver | # pip install undetected-chromedriver | ||
| </ | </ | ||