以下の内容はhttps://htn20190109.hatenablog.com/entry/2025/08/04/235232より取得しました。


web更新チェックシェル(mac)

https://prtn-life.com/blog/capture#toc4
https://qiita.com/jun_higuche/items/752ef756a182261fcc55

https://qiita.com/motoki1990/items/0274d8bcf1a97fe4a869
https://qiita.com/yuki-moroto/items/6d6e29b2dee194105ae7

https://ohenziblog.com/mac-cron_use_method/

https://www.pistolfly.com/weblog/2017/11/macos10-12-sierra%E4%BB%A5%E9%99%8D%E3%81%A7%E3%83%AD%E3%82%B0%E3%82%92%E8%A6%8B%E3%82%8B.html

https://www.gamingdeputy.com/jp/news/mac-%e3%81%a7%e3%82%b3%e3%83%9e%e3%83%b3%e3%83%89%e3%83%a9%e3%82%a4%e3%83%b3%e3%81%8b%e3%82%89-smb-%e5%85%b1%e6%9c%89%e3%82%92%e3%83%9e%e3%82%a6%e3%83%b3%e3%83%88%e3%81%99%e3%82%8b%e6%96%b9%e6%b3%95/

 

mac OS: Monterey 12.7.6

前提: 
メール送信(mac)設定済み
下記をrootのcrontabに設定済
*/10 * * * * /usr/sbin/postfix start

シェル名: check_web_updates.sh

設計:
seleniumスクリーンショット取得
②前回取得分と差分の比較
③差分が閾値以上ある場合、メール送信
④前回取得分を削除、今回ファイルを、前回ファイルにリネーム


注意事項:
OS再起動した場合、一度画面からログインしないとchromeを起動できない
shellでは全コマンドを原則、フルパスで記載する必要あり

 


confファイル:
check_web_updates.conf

URLキー,ヘッダーサイズ,閾値,URL値
csvファイル

(例)
key1,0,0.9,https://hoge.example.com
key2,400,0.9,https://fuga.example.com
key3,0,0.9,https://piyo.example.com

 

画像ファイル名:
<URLキー>_af.png
<URLキー>_bf.png

 

スクリーンショットを取得するPythonスクリプト

python3.11

 

pip3.11 install selenium
pip3.11 install chromedriver_binary

 

cat <<-'EOF' > get_screenshots.py

from selenium import webdriver
import chromedriver_binary
import time
import csv
import os
from selenium.webdriver.chrome.options import Options
from PIL import Image


base_dir_name =  '/Users/testuser/check_web_updates'
image_dir_name =  '/Volumes/share/Image'

options = Options()
options.add_argument('--headless')


# driver = webdriver.Chrome()
driver = webdriver.Chrome(options = options)

 

with open(base_dir_name + "/" + "check_web_updates.conf", "r", encoding="utf8") as csv_file:
  f = csv.reader(csv_file, delimiter=",", doublequote=True, lineterminator="\n", quotechar='"', skipinitialspace=False)
  for row in f:
    key = row[0]
    header = int(row[1])
    threshold = float(row[2])
    url = row[3]
    
    driver.get(url)
    driver.maximize_window()
    time.sleep(10)
    # ヘッダー変動画像回避
    if header > 0:
      driver.execute_script("window.scrollBy(0, " + str(header) + ");")
      time.sleep(5)
    
    driver.save_screenshot(image_dir_name +'/' + key + '_af.png')

    if 'xxx' in key:
      im = Image.open(image_dir_name +'/' + key + '_af.png')
      im_crop = im.crop((280, 200, 1200, 420))
      im_crop.save(image_dir_name +'/' + key + '_af.png', quality=95)


driver.close()

EOF

 


python3.11 get_screenshots.py

 

 


■2画像の画素値を比較し類似度を算出するPythonスクリプト


python3.11


pip3.11 install pillow


cat <<-'EOF' > diff_screenshots.py

import numpy as np
import os
import csv
import sys
from PIL import Image

base_dir_name =  '/Users/testuser/check_web_updates'
image_dir_name =  '/Volumes/share/Image'

output = ""

with open(base_dir_name + "/" + "check_web_updates.conf", "r", encoding="utf8") as csv_file:
  f = csv.reader(csv_file, delimiter=",", doublequote=True, lineterminator="\n", quotechar='"', skipinitialspace=False)
  for row in f:
    key = row[0]
    header = int(row[1])
    threshold = float(row[2])
    url = row[3]
    # print("key:" + key)
    # print("threshold:" + str(threshold) )
    # print("url:" + url)
    
    # print(type(threshold) )
    
    
    file1 = image_dir_name +'/' + key + '_bf.png'
    file2 = image_dir_name +'/' + key + '_af.png'
    
    # file1とfile2がある場合
    if os.path.exists(file1) and os.path.exists(file2):
      image1 = Image.open(file1)
      image2 = Image.open(file2)
      array1 = np.array(image1)
      array2 = np.array(image2)
      
      similarity = np.count_nonzero(array1 == array2) / np.count_nonzero(array1 == array1)
      
      image1_h = cv2.imread(file1)
      image2_h = cv2.imread(file2)
      image1_hist = cv2.calcHist([image1_h], [2], None, [256], [0, 256])
      image2_hist = cv2.calcHist([image2_h], [2], None, [256], [0, 256])
      similarity_h = cv2.compareHist(image1_hist, image2_hist, 0)
      
      if similarity < threshold and similarity_h < threshold:
        output = output + ';' + key

sys.stdout.write(output)

EOF

 

python3.11 diff_screenshots.py

 

■本体シェル

cat <<-'EOF' > check_web_updates.sh
#!/bin/bash

BASE_DIR_NAME=/Users/testuser/check_web_updates
IMAGE_DIR_NAME=/Volumes/share/Image

# 開始ログ
/bin/echo "[$(date '+%Y/%m/%d %H:%M:%S')] job start"  >> ${BASE_DIR_NAME}/check_web_updates.log

# 1. PCが起動していない場合、何もせずに終了する

/sbin/ping -c 1 10.11.21.1

if [ "$?" -ne "0" ] ; then
  exit 0
fi


# 2. Image_DIRをマウント
/usr/bin/open "smb://admin:admin@10.11.21.4/share"

/bin/sleep 10

# 3. 前回画像ファイルを削除、今回画像ファイルを、前回画像ファイルにリネーム


for i in $(/bin/cat ${BASE_DIR_NAME}/check_web_updates.conf) ; do

  key=${i%%,*}

  /bin/rm -rf "${IMAGE_DIR_NAME}/${key}_bf.png"
  /bin/mv "${IMAGE_DIR_NAME}/${key}_af.png" "${IMAGE_DIR_NAME}/${key}_bf.png"
done

 


# 4. スクリーンショット取得

/usr/local/bin/python3.11 ${BASE_DIR_NAME}/get_screenshots.py

# 5. 画像フィル差分比較

result=$(/usr/local/bin/python3.11 ${BASE_DIR_NAME}/diff_screenshots.py)
/bin/echo "${result}"


# 6. 該当がある場合、本文に記載しメール送信

: > "${BASE_DIR_NAME}"/wk
if [ -n "${result}" ] ; then
  result2="${result//;/\\n}"
  result3="${result//;/ }"
  builtin echo -e "${result2}" >> "${BASE_DIR_NAME}"/wk
  for key in $(echo "${result3}") ; do
    /usr/bin/uuencode "${IMAGE_DIR_NAME}/${key}_af.png" "${key}_af.png" >> "${BASE_DIR_NAME}"/wk
  done

  /bin/cat "${BASE_DIR_NAME}"/wk | /usr/bin/mail -s "website_updated" hoge@example.com
fi


# 7. Image_DIRをアンマウント
/sbin/umount /Volumes/share


# 終了ログ
/bin/echo "[$(date '+%Y/%m/%d %H:%M:%S')] job end"  >> ${BASE_DIR_NAME}/check_web_updates.log

exit 0

EOF

 


chmod +x check_web_updates.sh
./check_web_updates.sh


■クーロン登録

crontab -e

*/30 * * * * /Users/testuser/check_web_updates/check_web_updates.sh


crontab -l


log stream --info --predicate 'process == "cron"'
log show --info --predicate 'process == "cron"' --start '2017-05-25'

 

 




以上の内容はhttps://htn20190109.hatenablog.com/entry/2025/08/04/235232より取得しました。
このページはhttp://font.textar.tv/のウェブフォントを使用してます

不具合報告/要望等はこちらへお願いします。
モバイルやる夫Viewer Ver0.14