昨天把JS獲取內容的方式講完了,今天來說說py檔這邊的處理
├─ color_fetch.js #獲取文字顏色✅
├─ fetch.js #抓取網頁內容✅
├─ fetch.py #抓取網頁內容
└─ split.py #從網頁內容中分出粗體文字的部分
接著要開始使用selenium獲取網站內容。
feetch.py
# 從 selenium 導入 webdriver 與元素定位方式
from selenium import webdriver
from selenium.webdriver.common.by import By
# 導入 Chrome 選項
from selenium.webdriver.chrome.options import Options
# 導入作業系統模組
import os
chrome_option = Options()
#設定為不顯示視窗模式
chrome_option.add_argument("--headless")
# 建立 Chrome 無頭瀏覽器實例
browser = webdriver.Chrome(options=chrome_option)
# 要訪問的網址
url = "https://bluearchive.jp/news/newsJump"
# 設定等待網頁完全載入的時間
browser.implicitly_wait(10)
# 自訂函式抓取網頁內容
def fetch():
# 開啟網頁
browser.get(url)
# 尋找特定元素
catalogue_box = browser.find_element(By.CLASS_NAME, "catalogueBox")
# 取得分類選單中的所有 li 元素
li_element = catalogue_box.find_elements(By.TAG_NAME, "li")
# 取第一個 li 的文字作為分類,同時代表該li為最新的通知
category = li_element[0].text.split('\n')[0]
# 點擊最新的通知網頁
li_element[0].click()
# 將分類文字從日文轉換為英文
if category == 'お知らせ':
category = 'news'
elif category == 'メンテナンス':
category = 'maintenance'
elif category == 'イベント':
category = 'event'
# 切換到新開啟的分類網頁
browser.switch_to.window(browser.window_handles[-1])
# 讀取 JavaScript 檔案來抓取內容,這裡讀取昨天寫的兩個js檔
if os.path.exists('color_fetch.js'):
with open('color_fetch.js', 'r', encoding="utf-8") as f:
js_color = f.read()
if os.path.exists('fetch.js'):
with open('fetch.js', 'r', encoding="utf-8") as f:
js = f.read()
# 執行 JavaScript 取得內容
colors = browser.execute_script(js_color)
content = browser.execute_script(js)
# 建立暫存資料夾
if not os.path.exists('tmp'):
os.makedirs('tmp')
# 將JS取得的元素內容依序寫入文字檔
with open(f'./tmp/{category}.txt', 'w', encoding="utf-8") as f:
for txt in content:
f.write(txt.text+'\n')
# 讀取文字檔內容
with open(f'./tmp/{category}.txt', 'r', encoding="utf-8") as f:
content = f.read()
# 讀取並分段文字
return content, browser.current_url, colors
# 測試呼叫函式
print(fetch())
透過上面程式可以利用我們昨天寫的兩個抓取特定網頁元素並回傳相關內容的JS就可取得我們想要的網頁資訊。
接著需要將文字檔內容不同樣式的字體取出來,也就是我們在JS經過預先處理過的粗體文字。
split.py
# 讀取文字檔
def read(category):
# 以讀取模式開啟文字檔
with open(f"./tmp/{category}.txt", 'r', encoding="utf-8") as f:
# 讀取檔案內容
t = f.read()
# 將內容分割為陣列
t = t.split('\n ')
# 傳回內容陣列給part函式
return part(t)
# 從陣列中擷取文字區塊
def fetch(part, symbol):
# 找到標記符號起始位置
start = part.find(symbol)
# 刪除第一個標記符號
part = part.replace(symbol, '', 1)
# 找到標記符號結束位置
end = part.find(symbol)
# 刪除第二個標記符號
part = part.replace(symbol, '', 1)
# 傳回擷取之文字與標記符號包覆的文字
return (part, part[start:end])
# 分割文字陣列中的區段
def part(tlist):
# 儲存加底線區段的陣列
strong_list = []
# 迭代文字陣列
for index, t in enumerate(tlist):
# 目前處理的文字
text = t
# 當文字有底線標記時
while True:
# 檢查是否有底線符號
if('_' in text):
# 擷取底線區段
result = fetch(text, '_')
# 將底線區段儲存
strong_list.extend(result[1:])
# 保留剩餘文字
text = result[0]
# 如果沒有找到底線符號則跳出
else:
break
# 用處理後的文字取代原文字
tlist[index] = text
# 傳回分割後的文字陣列與底線文字陣列
return tlist, strong_list
以上程式中我們將原本(有包含粗體字)的內容將文本和粗體字分出來,並把底線刪除後替代掉原有的文本,如此之後便可判斷哪段文字應該是何種字體樣式,以方便還原。
到此我們已經成功使用selenium將網站內容取得後並經過一些前置處理,方便我們之後處理資料。接下來兩天會將Discord bot建立好後,將爬蟲程式加入,使得Discord bot可以使用爬蟲取得最新消息。