Python:自動でZoomに参加する
準備
OS:
MacOS Sonoma 14.2.1
ENV:
python 3.12.5
opencv 4.10.0
opencv-python 4.10.0
selenium 4.24.0
PyAutoGui 0.9.54
chromedriver_autoinstaller 0.6.4
Pillow 10.4.0
カーネルに入っていないモジュールをインストールしてから、インポートする。
import subprocess
import importlib
import sys
Required_Modules=['selenium','chromedriver_autoinstaller','pyscreeze','time','datetime','pyautogui','opencv-python','Pillow']
for module in Required_Modules:
try:
importlib.import_module(module)
except ImportError as e:
print(f'install {module}')
subprocess.check_call([sys.executable, '-m', 'pip', 'install', module])
from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.chrome.options import Options
import chromedriver_autoinstaller
from selenium.webdriver.common.by import By
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.common.exceptions import NoAlertPresentException
from selenium.common.exceptions import TimeoutException
import pyscreeze
from pyscreeze import ImageNotFoundException
pyscreeze.USE_IMAGE_NOT_FOUND_EXCEPTION = True
import time
import datetime
from sys import exit
import pyautogui as pa
chromedriver_autoinstaller.install()
pa.useImageNotFoundException()
seleniumが制御できるポップアップウィンドウは、"OK"が前提の単純な警告、ユーザーIDやパスワードの入力が必要なprompt alert、サイトを閉じる等の承認を得るconfirmation alertの三つである。
Chromeのサイトで、Developer Toolsからセレクトモードで、サイトのどの部分がどのソースコードで制御されるか確認できる。
逆に言えば、このソースコードに出てこないポップアップウィンドウは、ブラウザが出しているのではなく、起動を要求されているアプリのOSのコントロール下にあるので、Seleniumではコントロールできない。このため、最も簡単な方法として、PyAutoGuiの画面位置確認とクリック機能を使用する。
zoomアプリが制御している"Open zoom.us?"ポップアップウィンドウの"Open zoom.us"ボタンの画像を撮り、zoom_us.pngとして保存する。
同様に、パスコードを必要とするミーティングの時には、
をzoom_pc.pngとして保存する。
Zoomでは、有料の場合は、ホスト側で、ホストが認証するまで待機室からの入室とパスコード入室が選べるが、無料版ではこのパスコード入室がデフォルトになっている。
最後の入室ボタンの画像も保存する。
Python Selenium
seleniumでブラウザを立ち上げ、zoom.us/joinでMeetingIDを入れ、クッキーを承諾するコードは以下のようになる。
def StartZOOM(MeetingID,url):
driver = webdriver.Chrome()
driver.get(url)
driver.maximize_window()
wait = WebDriverWait(driver,60)
time.sleep(3)
try:
WebDriverWait(driver, 10).until(EC.element_to_be_clickable((By.XPATH,'//button[@id="onetrust-accept-btn-handler"]'))).click()
print("accepted cookies")
except Exception as e:
print('no cookie button')
target = driver.find_element(By.ID,"join-confno")
target.send_keys(MeetingID)
btn = driver.find_element(By.ID,"btnSubmit").click()
return driver
画像位置の取得
zoom_us.png, zoom_pc.png, zoom_join.pngの画像の位置を取得するコードは以下のようになる。
def FindLoc(pngfile):
while True:
try:
p= pa.locateCenterOnScreen(pngfile,grayscale=False,confidence=0.7)
if(p is not None):
print('location:',p)
break
except pa.ImageNotFoundException:
print(" Image not found, will exit")
sc = pa.screenshot()
name = 'screenshot%s.png' % (datetime.datetime.now().strftime('%Y-%m%d_%H-%M-%S-%f'))
sc.save(name)
exit()
return p
画像が見つからなかった場合、スクリーンショットを保存する。
ミーティングの時間設定
終了時間が過ぎたら、退出するため、ミーティングの時間を設定する。
def MeetingMinute(MeetingDuration):
minutes =0
second = 0
if MeetingDuration[-1]=='h' :
minutes=60*float(MeetingDuration[:-1]))
elif MeetingDuration[-1]=='m':
minutes= float(MeetingDuration[:-1])
return 60*minutes
メインのコードでtime.sleep()を使うので、最後に秒に直す。また、実数時間指定は繰り上げて整数にしている。
自動入室
上記の関数を書き込んだファイルをPyZoomとし、PZでインポートし、MeetingID、Meeting Passcodeの有無、MeetingDurationを指定する。入室後はマイクをミュートにし、ミーティング時間が経過したら、退出のプロンプトが出て退出する。
def AutoZoom(MeetingID,MeetingDuration,url='http://zoom.us/join',Passcode=None):
driver=StartZOOM(MeetingID,url)
time.sleep(3)
p_zu=FindLoc('zoom_us.png')
pa.moveTo(p_zu.x/2,p_zu.y/2)
pa.click(p_zu.x/2, p_zu.y/2,clicks=2, interval=1)
time.sleep(3)
if Passcode is not None:
time.sleep(5)
p_pc=FindLoc('zoom_pc.png')
pa.moveTo(p_pc.x/2,p_pc.y/2)
pa.write(Passcode)
pa.press('enter')
else:
time.sleep(10)
p_join=FindLoc('zoom_join.png')
pa.moveTo(p_join.x/2,p_join.y/2)
pa.click(p_join.x/2, p_join.y/2,clicks=2, interval=1)
time.sleep(10)
# Mute own mic
pa.hotkey('command','shift','A')
time.sleep(3)
pa.hotkey('enter')
time.sleep(MeetingMinute(MeetingDuration))
#Leaving prompt
pa.hotkey('command','q')
time.sleep(3)
pa.hotkey('enter')
driver.close()
pyAutoGuiで得られている位置を2で割っているのは、Mac上では位置が2倍で出力されるからである。
main で、AutoZoomを呼び出す。
import PyZoom as PZ
MeetingID='XXX XXXX XXXX'
Passcode='XXXXXX'
MeetingDuration='0.5h'
PZ.AutoZoom(MeetingID,MeetingDuration,Passcode=Passcode)