first commit

This commit is contained in:
Victor Chang 2025-02-28 03:48:54 +00:00
commit b4a8c8dbd4
4 changed files with 189 additions and 0 deletions

2
README.md Normal file
View File

@ -0,0 +1,2 @@
Run main.py
Monitor website every 2 hours and send Line message to target groupe if updates

Binary file not shown.

148
main.py Executable file
View File

@ -0,0 +1,148 @@
import requests
import time
from bs4 import BeautifulSoup
import hashlib
import datetime
import screenshot
import os
try:
from zoneinfo import ZoneInfo
except ImportError:
from backports.zoneinfo import ZoneInfo # type: ignore for VS Code
# === LINE API 設定 ===
LINE_ACCESS_TOKEN = "uwfN1kiAdFfPoTF4QD8AFC0zO05tT341MBFxXk3n5wT/PAOvshAJqUei3EupTyxIgaTNhBF7zcDBTcq3Hg4SffYr1of0iREPqoCSYIpAS9MSnQ1EGDoYpquvzrDv8i4P8nwnOh/+vu/K/PcFs7QKqAdB04t89/1O/w1cDnyilFU="
USER_ID = "C3c225be8353b74ecfaa202d5ae9c182c" # piccc group
LINE_API_URL = "https://api.line.me/v2/bot/message/push"
# 本机图片路径
IMAGE_PATH = "screenshot.png"
headers = {
"Content-Type": "application/json",
"Authorization": f"Bearer {LINE_ACCESS_TOKEN}"
}
def send_message():
data = {
"to": USER_ID,
"messages": [
{
"type": "text",
"text": "吉美網頁有新更新!請查看系統。"
}
]
}
response = requests.post(LINE_API_URL, headers=headers, json=data)
if response.status_code == 200:
print("訊息發送成功!")
else:
print(f"發送失敗,錯誤代碼:{response.status_code}")
print(response.text)
def send_image():
headers = {
"Content-Type": "application/json",
"Authorization": f"Bearer {LINE_ACCESS_TOKEN}",
}
# 先上传图片到外部服务器(因为 LINE API 需要图片的 URL
image_url = upload_image_to_imgur(IMAGE_PATH)
if not image_url:
print("图片上传失败")
return
# 发送消息
payload = {
"to": USER_ID,
"messages": [
{
"type": "image",
"originalContentUrl": image_url, # 图片的 URL
"previewImageUrl": image_url, # 预览图的 URL
}
],
}
response = requests.post(LINE_API_URL, json=payload, headers=headers)
print(response.json())
# 使用 Imgur API 上传图片(或你自己的图床)
def upload_image_to_imgur(image_path):
IMGUR_CLIENT_ID = "5e67dbdeaafc7dc" # 需要去 Imgur 申请
headers = {"Authorization": f"Client-ID {IMGUR_CLIENT_ID}"}
with open(image_path, "rb") as f:
files = {"image": f}
response = requests.post("https://api.imgur.com/3/upload", headers=headers, files=files)
if response.status_code == 200:
return response.json()["data"]["link"]
else:
print("图片上传失败:", response.json())
return None
# === 目標網址與 session 設定 ===
homepage_url = "https://tccmoapply.dba.tcg.gov.tw/tccmoapply/" # 首頁,先訪問以建立 session
target_url = "https://tccmoapply.dba.tcg.gov.tw/tccmoapply/maliapp/asp/aspcons_f000.jsp?MODE=SAVE&KIND=01&YY=109&NO1=0267&NO2=00&CG=05" # 目標頁面
check_interval = 7200 # 每 7200 小時檢查一次 7200
# === 取得網頁內容並計算 Hash ===
def get_page_content():
with requests.Session() as session:
# 先訪問首頁以建立 session
session.get(homepage_url)
# 訪問目標網頁
response = session.get(target_url)
if response.status_code != 200:
print(f"請求失敗,錯誤代碼:{response.status_code}")
return ""
soup = BeautifulSoup(response.text, 'html.parser')
# 找出網頁內的主要內容
main_content = soup.find("table") # 你可以改成特定的 `div` 或 `section`
return main_content.text.strip() if main_content else ""
def get_content_hash(content):
return hashlib.md5(content.encode()).hexdigest()
def now_time():
now_utc = datetime.datetime.now(ZoneInfo("UTC"))
taipei_time = now_utc.astimezone(ZoneInfo("Asia/Taipei"))
return taipei_time.strftime("%Y-%m-%d %H:%M:%S")
previous_hash = ""
while True:
try:
page_content = get_page_content()
current_hash = get_content_hash(page_content)
if previous_hash and current_hash != previous_hash:
print(f"{now_time()}: 網頁有更新!")
screenshot.screenshot()
send_message()
send_image()
time.sleep(3)
os.remove(IMAGE_PATH)
else:
print(f"{now_time()}: 沒有變更")
'''
screenshot.screenshot()
send_message()
send_image()
time.sleep(3)
os.remove(IMAGE_PATH)
'''
previous_hash = current_hash
time.sleep(check_interval)
except Exception as e:
print(f"ERROR: {e}")
time.sleep(check_interval)

39
screenshot.py Executable file
View File

@ -0,0 +1,39 @@
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
import time
def screenshot():
options = Options()
options.add_argument("--headless") # 無頭模式
options.add_argument("--no-sandbox") # 避免權限問題
options.add_argument("--disable-dev-shm-usage") # 避免資源不足
options.add_argument("--disable-gpu") # 某些系統需要這個
options.add_argument("--window-size=800x600") # 設定解析度
# 啟動瀏覽器
driver = webdriver.Chrome(options=options)
# 先訪問首頁,讓 Session 建立
driver.get("https://tccmoapply.dba.tcg.gov.tw/tccmoapply/")
print("Waiting for session to establish...")
time.sleep(2) # 等待 2 秒確保 session 建立
# 再跳轉到目標頁面
target_url = "https://tccmoapply.dba.tcg.gov.tw/tccmoapply/maliapp/asp/aspcons_f000.jsp?MODE=SAVE&KIND=01&YY=109&NO1=0267&NO2=00&CG=05"
driver.get(target_url)
print("Navigated to target page, waiting for it to load...")
time.sleep(2) # 等待 2 秒確保頁面載入完整
# 滾動到頁面底部
driver.execute_script("window.scrollTo(0, document.body.scrollHeight);")
print("Scrolling to the bottom...")
time.sleep(3) # 等待 3 秒確保頁面完全載入
# 截取整個頁面
driver.save_screenshot("screenshot.png")
print("Screenshot saved as 'screenshot.png'")
# 關閉瀏覽器
driver.quit()
if __name__ == '__main__':
screenshot()