上週社區網路停業後, 佈署在高雄家 Pi 3 主機上的爬蟲全部停擺, 週三 (10/3) 中華電信來安裝光世代 300M 後網路可用了, 但 Pi 3 因為之前使用 RJ45 網路線連網, 必須重新設定才能運作, 為了能讓爬蟲恢復運轉我先把母校圖書館借書與預約爬蟲程式移到 Pi 400 上跑, 但出現執行錯誤, 詢問 AI 才知在樹莓派 Trixie OS 上 Selenium 調用 Chromium webdriver 的方式已經不同 :
1. 改用新套件 :
在 Debian 12 (Bookworm) 之後的版本, chromium-browser 與 chromium-chromedriver 套件已被移除, 要改用 chromium 與 chromium-driver 套件, 所以要先安裝這兩個套件 :
sudo apt update
sudo apt install -y chromium chromium-driver
pi@pi3aplus:~ $ sudo apt install -y chromium chromium-driver
Upgrading:
chromium chromium-common chromium-l10n chromium-sandbox
Installing:
chromium-driver
Summary:
Upgrading: 4, Installing: 1, Removing: 0, Not Upgrading: 83
Download size: 171 MB
Space needed: 19.5 MB / 43.7 GB available
下載:1 http://archive.raspberrypi.com/debian trixie/main arm64 chromium-l10n all 1:142.0.7444.175-1~deb13u1+rpt1 [19.4 MB]
下載:2 http://archive.raspberrypi.com/debian trixie/main arm64 chromium arm64 1:142.0.7444.175-1~deb13u1+rpt1 [106 MB]
下載:3 http://archive.raspberrypi.com/debian trixie/main arm64 chromium-common arm64 1:142.0.7444.175-1~deb13u1+rpt1 [36.0 MB]
下載:4 http://archive.raspberrypi.com/debian trixie/main arm64 chromium-sandbox arm64 1:142.0.7444.175-1~deb13u1+rpt1 [113 kB]
下載:5 http://archive.raspberrypi.com/debian trixie/main arm64 chromium-driver arm64 1:142.0.7444.175-1~deb13u1+rpt1 [8,756 kB]
取得 171 MB 用了 52s (3,260 kB/s)
apt-listchanges: 讀取改變紀錄中...
(讀取資料庫 ... 目前共安裝了 125708 個檔案和目錄。)
正在準備解包 .../chromium-l10n_1%3a142.0.7444.175-1~deb13u1+rpt1_all.deb……
Unpacking chromium-l10n (1:142.0.7444.175-1~deb13u1+rpt1) over (1:142.0.7444.162
-1~deb13u1+rpt1) ...
正在準備解包 .../chromium_1%3a142.0.7444.175-1~deb13u1+rpt1_arm64.deb……
Unpacking chromium (1:142.0.7444.175-1~deb13u1+rpt1) over (1:142.0.7444.162-1~de
b13u1+rpt1) ...
正在準備解包 .../chromium-common_1%3a142.0.7444.175-1~deb13u1+rpt1_arm64.deb……
Unpacking chromium-common (1:142.0.7444.175-1~deb13u1+rpt1) over (1:142.0.7444.1
62-1~deb13u1+rpt1) ...
正在準備解包 .../chromium-sandbox_1%3a142.0.7444.175-1~deb13u1+rpt1_arm64.deb……
Unpacking chromium-sandbox (1:142.0.7444.175-1~deb13u1+rpt1) over (1:142.0.7444.
162-1~deb13u1+rpt1) ...
選取了原先未選的套件 chromium-driver。
正在準備解包 .../chromium-driver_1%3a142.0.7444.175-1~deb13u1+rpt1_arm64.deb……
Unpacking chromium-driver (1:142.0.7444.175-1~deb13u1+rpt1) ...
設定 chromium-sandbox (1:142.0.7444.175-1~deb13u1+rpt1) ...
設定 chromium-common (1:142.0.7444.175-1~deb13u1+rpt1) ...
設定 chromium (1:142.0.7444.175-1~deb13u1+rpt1) ...
設定 chromium-driver (1:142.0.7444.175-1~deb13u1+rpt1) ...
設定 chromium-l10n (1:142.0.7444.175-1~deb13u1+rpt1) ...
執行 desktop-file-utils (0.28-1) 的觸發程式……
執行 hicolor-icon-theme (0.18-2) 的觸發程式……
執行 gnome-menus (3.36.0-3) 的觸發程式……
執行 libc-bin (2.41-12+rpt1) 的觸發程式……
執行 man-db (2.13.1-1) 的觸發程式……
執行 mailcap (3.74) 的觸發程式……
pi@raspberrypi:~ $ which chromium
which chromedriver
/usr/bin/chromium
/usr/bin/chromedriver
安裝好後用 which 指令查詢 :
pi@pi3aplus:~ $ which chromium
/usr/bin/chromium
pi@pi3aplus:~ $ which chromedriver
/usr/bin/chromedriver
2. 改用新寫法 :
匯入套件 :
from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.chrome.options import Options
設定無頭存取選項物件 & 建立 Chorme 瀏覽器物件 :
options=Options()
options.add_argument("--headless=new")
options.add_argument("--no-sandbox")
options.add_argument("--disable-dev-shm-usage")
options.binary_location="/usr/bin/chromium"
service=Service("/usr/bin/chromedriver")
browser=webdriver.Chrome(service=service, options=options)
3. 爬蟲程式改版 :
依照上面新寫法將爬蟲程式改為 v10 版 :
# nkust_lib_10.py
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.common.action_chains import ActionChains
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.chrome.service import Service
import time
import requests
from datetime import datetime
import asyncio
from telegram import Bot
import re
async def telegram_send_text(text):
bot=Bot(token=token)
try:
await bot.send_message(
chat_id=chat_id,
text=text
)
return True
except Exception as e:
print(f'Error sending text: {e}')
return False
def get_nkust_lib():
browser=None
msg="無法取得資料" # ✅ 防止未賦值
try:
options=Options()
options.add_argument("--headless=new")
options.add_argument("--no-sandbox")
options.add_argument("--disable-dev-shm-usage")
options.binary_location="/usr/bin/chromium"
service=Service("/usr/bin/chromedriver")
browser=webdriver.Chrome(service=service, options=options)
browser.implicitly_wait(60)
browser.set_window_size(1920, 1080)
url=(
'https://nkust.primo.exlibrisgroup.com/discovery/login?'
'vid=886NKUST_INST:86NKUST&lang=zh-tw'
)
browser.get(url)
# 按其他讀者
md_list=browser.find_elements(By.TAG_NAME, 'md-list-item')
if len(md_list) > 1:
md_list[1].click()
print('按其他讀者 ... OK')
# 登入系統
login_user_name=browser.find_element(By.ID, 'LoginUserName')
login_user_name.send_keys('我的帳號')
login_password=browser.find_element(By.ID, 'LoginPassword')
login_password.send_keys('我的密碼')
login_btn=browser.find_element(By.CLASS_NAME, 'button-large')
login_btn.click()
print('登入系統 ... OK')
# 按名字顯現選單
user_btn=browser.find_element(By.CLASS_NAME, 'user-button')
actions=ActionChains(browser)
actions.move_to_element(user_btn)
actions.click(user_btn)
actions.perform()
print('按名字顯現選單 ... OK')
# 按我的借閱鈕
xpath='/html/body/div[3]/md-menu-content/md-menu-item[3]/button'
my_borrow=browser.find_element(By.XPATH, xpath)
actions.move_to_element(my_borrow)
actions.click(my_borrow)
actions.perform()
print('按我的借閱 ... OK')
# 按全部續借
xpath=(
'/html/body/primo-explore/div/prm-account/md-content'
'/div[2]/prm-account-overview/md-content/md-tabs/'
'md-tabs-content-wrapper/md-tab-content[2]/div/'
'div/prm-loans/div[1]/div[2]/div[2]/button'
)
all_borrow=browser.find_element(By.XPATH, xpath)
actions.move_to_element(all_borrow)
actions.click(all_borrow)
actions.perform()
print('按全部續借 ... OK')
# 檢查續借結果
xpath=(
'/html/body/primo-explore/div/prm-account/md-content'
'/div[2]/prm-account-overview/md-content/md-tabs'
'/md-tabs-content-wrapper/md-tab-content[2]/div/div'
'/prm-loans/div[2]/prm-alert-bar/div/div/span'
)
alert_span=browser.find_element(By.XPATH, xpath)
if '所有借閱資料已成功續借' in alert_span.text:
msg='❖ 所有借閱資料已成功續借'
else:
msg='❖ 只有部分借閱資料已成功續借'
# 檢查是否有 "載入更多結果" 按鈕
for i in range(3): # 最多 3 頁
load_more=browser.find_elements(By.CLASS_NAME, 'button-confirm')
if not load_more:
break
load_more[0].click()
time.sleep(2)
# 抓取所有借閱書目
loan_items=browser.find_elements(By.TAG_NAME, 'md-list-item')
unrenew_books=[]
for item in loan_items:
try:
# ✅ 1. 必須有書名才是書
title_elem=item.find_elements(By.CSS_SELECTOR, "h3 a")
if not title_elem:
continue
title=title_elem[0].text.strip()
item_text=item.text.strip()
# ✅ 2. 取得到期日
due_text=''
due_elem=item.find_elements(By.XPATH, './/p[@data-qa="automation_mlc_record_date"]')
if due_elem:
m=re.search(r'\d{2}/\d{2}/\d{4}', due_elem[0].text)
if m:
due_text=m.group(0)
# ✅ 3. 只收真正「被預約 / 無法續借」
if any(k in item_text for k in ["被預約", "無法續借", "recall"]):
unrenew_books.append((title, due_text))
except Exception:
continue
if unrenew_books:
msg="被預約的書:\n" + "\n".join(
[f"{i+1:>2}. {t[0]} 到期日: {t[1]}" for i, t in enumerate(unrenew_books)]
)
else:
msg="全部書籍皆已續借"
print('搜尋被預約書籍 ... OK')
except Exception as e:
print(e)
finally:
if browser:
browser.quit() # ✅ 防呆
return msg # ✅ msg 一定有值
if __name__ == '__main__':
start=time.time()
msg=get_nkust_lib()
token='我的Telegram Token'
chat_id='Telegram聊天室 ID'
if msg:
now=datetime.now().strftime('%Y-%m-%d %H:%M:%S')
msg='\n' + now + '\n' + msg
if asyncio.run(telegram_send_text(msg)):
print('訊息傳送成功!')
else:
print('訊息傳送失敗!')
print(msg)
end=time.time()
print(f'執行時間:{end-start}')
進入虛擬環境測試 :
pi@pi3aplus:~ $ source ~/myenv313/bin/activate
(myenv313) pi@pi3aplus:~ $ python nkust_lib_10.py
按其他讀者 ... OK
登入系統 ... OK
按名字顯現選單 ... OK
按我的借閱 ... OK
按全部續借 ... OK
搜尋被預約書籍 ... OK
訊息傳送成功!
2025-12-07 13:16:35
被預約的書:
1. 持續買進 : 資料科學家的投資終極解答, 存錢及致富的實證方法 / 尼克.馬朱利(Nick Maggiulli)著 ; 李芳齡譯 (c.3) 到期日: 12/31/2025
執行時間:573.5429089069366
花了快 10 分鐘, 好久 !
4. 設定 crontab :
先用 chmod 將爬蟲程式添加可執行權限 :
pi@pi3aplus:~ $ chmod +x nkust_lib_10.py
pi@pi3aplus:~ $ ls -ls nkust_lib_10.py
8 -rwxrwxr-x 1 pi pi 6039 12月 7 10:43 nkust_lib_10.py
編輯 crontab, 設定於 06:00, 12:00, 與 16:00 執行此程式 :
pi@pi3aplus:~ $ crontab -e
crontab: installing new crontab
pi@pi3aplus:~ $ crontab -l
*/3 * * * * curl -s https://serverless-fdof.onrender.com/function/hello
*/3 * * * * curl -s https://serverless-5e6i.onrender.com/function/hello
0 6,12,16 * * * /home/pi/myenv313/bin/python /home/pi/nkust_lib_10.py

沒有留言 :
張貼留言