我們來運用前面的技術來個應用案例,廢話不多說直接開始。
這次步驟有幾個:從維基文庫利用爬蟲爬下資料 -> 清理資料包含整理欄位、字串處理 -> 制定分析框架如看熱詞、看重要詞彙、找議題看變化 -> 訓練詞嵌入模型 -> 視覺化並輸出。
因為這邊步驟前面都提過,我們等等直接進入到資料部分。
不過,在此之前,我們可以看一下「專家」針對今年國慶演說,有什麼觀察。
以遠見雜誌這篇蔡總統國慶演說解析》學者評價兩極:兩岸關係比扁時代還退步來說,找了兩位受訪者。
第一位受訪者是這樣評價的:
「蔡president試圖總結過去執政階段的國家建設、期待,以及擘畫未來的發展,」兩岸政策協會研究員吳瑟致評價蔡English最後一次國慶演講,以她講稿中論及的民主、韌性,國際和兩岸間的情勢發展、台灣的立足點等各段篇幅,認為蔡English找到了自己的歷史定位。
還有這一段:
蔡English這次的國慶演說,跟緊接而來的2024年總統大選,無可避免會產生一定的政治聯繫。「她提及了包括民主、捍衛主權,兩岸的一些切面,以及國際的情勢,試圖連結明年總統大選的重要性。」吳瑟致總結,這次蔡English的講稿共有三個觀察重點,分別為:她的歷史定位、總結過往的施政表現,以及下個接棒者該有的國家願景擘畫。
第二位受訪者則這樣說:
但對於蔡English這次國慶演講中,花費許多篇幅的內政政績,淡江大學陸研所榮譽教授趙春山卻潑了冷水。他說,蔡English雖細數諸如軍公教年改、能源轉型、社宅等政策,但這些政績已經經過檢驗,「去年九合一大選,選舉結果已表示蔡的內政方面不行。」
其他方面,趙春山指出,台美關係、國防政策是蔡English執政7年多來較為突出的兩點,講稿中提到了AI、半導體等高科技的發展,以及台灣地緣政策的重要性,但「那都是作為美國圍堵中國的一個棋子,台美關係確實有所強化,這是她最大的成就,」但除了這兩點之外,其他面向都乏善可陳。
我不表達政治立場,也不針對政治判斷評價,單純就「文本」反映出什麼來說,吳瑟致做的是「描述」,他歸納出重點、給出總結;趙春山則不只有描述,更試圖「詮釋」,他批評演講跟政績對不起來、講其他面向乏善可陳。
我認為吳瑟致的做法,比趙春山好。問題不在趙春山講的內容究竟是不是對的,因為那可以另外檢驗。關鍵在於,我們能夠從文本看到足夠多的東西,即便不連結現實,也有太多東西可以挖掘。如果是趙春山的評價方式,那根本不用看蔡English的演講稿,就可以細數蔡English任內的表現不好之處了。
底下就會展示,要怎麼從文字資料中挖掘出洞見。
我們先來到維基文庫,可以看到有一個分类:中華民國總統國慶大會致詞,原文就是簡體的,不是我改的。
裡面有中華民國三十年國慶紀念告全國軍民書、中華民國五十五年國慶紀念告全國軍民同胞書,斷斷續續的有到中華民國六十年國慶紀念告全國軍民同胞書,可是緊接著就是總統蒞臨中華民國八十六年國慶大會致詞,接下來就可以一直到總統蒞臨中華民國一一二年國慶大會致詞,也就是最新一年的致詞。
所以,我們就是要從八十六年國慶大會致詞,一路抓到一一二年國慶大會致詞。
底下就是程式碼,我會一步一步解釋。
首先載入套件。
library(tidyverse)
library(rvest)
library(httr)
接著制定超連結的架構,因為網址是變動的。這步驟要學會如何觀察網址的變化。
url_pre <- "https://zh.wikisource.org/wiki/"
url_medium <- "總統蒞臨中華民國"
url_last <- "年國慶大會致詞"
year_big <- c("八十","九十","一○","一一")
year_small <- c("○","一","二","三","四","五","六","七","八","九")
我們會利用雙層for loop抓資料。
index_big <- 1
df_speech_ten <- tibble()
for (i in index_big:4) {
因為八十年的時候是從86年開始,所以要多寫一個 if else 條件判斷。
i <- index_big
if(year_big[i] == "八十"){
index_small <- 7
} else{
index_small <- 1}
因為一百一十年的時候只有到一一二年,所以同樣要多寫一個 if else 條件判斷。
if(year_big[i] == "一一"){
index_small_end <- 3
} else{
index_small_end <- 10}
外面的大圈,也就是年份的十年部分搞定,接著要進入內圈,也就是個位數的年份部分。
for (j in index_small:index_small_end) {
再度面對條件判斷,因為碰到90、100、110的時候名字都有另外叫法,所以要直接寫一百跟九十。
j <- index_small
if(year_big[i] == "一○" & year_small[j] == "○"){
url_change <- "一百"
} else if(year_big[i] == "九十"& year_small[j] == "○"){
url_change <- "九十"
} else {
url_change <- str_c(year_big[i], year_small[j])
}
因為觀察原始資料發現,進入到110年以後,維基文庫的結構出現變化,所以要調成爬蟲的程式碼。因此加入 if else 條件判斷。
if(year_big[i] == "一一"){
url <- str_c(url_pre, url_medium, url_change, url_last)
html <- url %>% read_html()
主要差別發生在實際上抓到的 text 裏面。html_nodes的取法就有差異。
text <- html %>% html_nodes("#content") %>% html_nodes("p") %>% html_text();text
text <- text[1:(length(text)-2)] %>% str_c(collapse = "")
df_tmp <- tibble(text = text[1], url = url, year = url_change)
df_speech_ten <- df_speech_ten %>% bind_rows(df_tmp) %>% select(year, url, text)
message(url_change)
index_small <- index_small + 1
Sys.sleep(5)
} else {
url <- str_c(url_pre, url_medium, url_change, url_last)
html <- url %>% read_html()
你可以發現這邊取的node不一樣。
text <- html %>% html_nodes("p") %>% html_text();text
df_tmp <- tibble(text = text[1], url = url, year = url_change)
df_speech_ten <- df_speech_ten %>% bind_rows(df_tmp) %>% select(year, url, text)
message(url_change)
每跑完一圈內圈 counter + 1。
index_small <- index_small + 1
Sys.sleep(5)
}
}
每跑完一圈外圈 counter + 1。
index_big <- index_big + 1
}
最後就是輸出,資料就大功告成!
# df_speech_ten %>% write_rds("data/總統國慶致詞/")
df_speech_ten %>% write_rds("data/df_speech_ten.rds")
為什麼評價是「蔡president」跟「蔡English」啊,原文看起來不是這樣?
蔡English的中文全名是ithome系統的敏感詞彙~無法直接使用!我有寫信去問官方得到的答案!所以貼上來之前用尋找與取代修掉了
布丁大大看得好認真!我有聽過您演講~
什麼,居然是敏感詞! XD
官方回應說之前有人洗版所以有暫時阻擋,現在有調整機制,應該可以使用了!也是一個string detection的好案例!