爬蟲(Web Crawling)是這幾年來依然很熱門的主題,對於財金的應用也愈來愈多,這篇文章是我R的研究筆記的其中一部分,希望對R的初學者有些幫助,降低進入障礙。以財經新聞為例,大部分的新聞資料除非跟相關單位購買(通常很貴!),最好的辦法就是爬蟲了!爬蟲簡單來說就是去擷取特定網頁上的資料,經過篩選與整理後就可以拿來做統計或是其他分析了,以下著重討論爬蟲的初階作法,關於爬蟲時可能遇到“帳密登入”、“連線逾時”等等問題,這邊就不贅述囉,有興趣的話可能以後會再分享。
在正式開始前,記得載入需要的套件。每次Rstudio重新執行時,所有的套件都會是未搭載的狀態,記得重新載入,這部分R與Python非常類似,習慣使用SAS等套裝軟體的人可能會不習慣。
library(rvest) # 爬蟲相關套件
library(httr) # 爬蟲相關套件
library(dplyr) # 非常強大的資料處理套件
library(lubridate) # 處理日期變數的套件
library(stringr) # 處理字串的套件
以MoneyDJ 新聞摘錄網站為例,我們要先爬取它的首頁(http://blog.moneydj.com/news/),找到網址後開始運用套件的函數將該網頁的資料下載下來。
url <- "http://blog.moneydj.com/news/"
doc <- read_html(url, encoding = "UTF-8")
第二步開始針對我們的目標頁面(url)抓取我們需要的「新聞標題」以及「各篇新聞的子連結」,我們要有子連結才能夠爬取文章內容,在抓各家新聞網站時通常都是這種方法。而發布時間剛好在這裡也可以取得,時間變數在財經的分析上非常重要,因此我習慣都先將時間變數處理好。
# 取得新聞標題
header <- doc %>%
html_nodes(".entry-title.mh-loop-title") %>%
html_nodes("a") %>%
html_text()
head(header, n = 1L) # 檢查檔案
## [1] " 《美債》10年債殖利率摔20個月低 殖利率曲線部分倒掛 "
# 取得新聞的文章子連結
link <- doc %>%
html_nodes(".entry-title.mh-loop-title") %>%
html_nodes("a") %>%
html_attr("href")
# 取得發布時間
d <- doc %>%
html_nodes("span.mh-meta-date.updated") %>%
html_text()
head(link, n = 1L) # 檢查檔案
## [1] "https://blog.moneydj.com/news/2019/05/29/%e3%80%8a%e7%be%8e%e5%82%b5%e3%80%8b10%e5%b9%b4%e5%82%b5%e6%ae%96%e5%88%a9%e7%8e%87%e6%91%9420%e5%80%8b%e6%9c%88%e4%bd%8e-%e6%ae%96%e5%88%a9%e7%8e%87%e6%9b%b2%e7%b7%9a%e9%83%a8%e5%88%86%e5%80%92/"
第三步會結合迴圈來批次爬取我們連結對應的文本,程式碼如下:
# 先創造一個空的物件,準備將所有文章內容合併在同一個物件中
article.all <- c()
for(i in 1:length(link)) {
doc.a <- read_html(link[i])
article <- doc.a %>%
html_nodes("div.entry-content.mh-clearfix") %>%
html_nodes("p") %>%
html_text() %>%
str_c(collapse = "")
article.all <- append(article.all, article)
}
# 最後轉為data.frame格式,以便後面做分析
df <- data.frame(title = header, content = article.all)
大部分的新聞網站會提供瀏覽歷史新聞的功能,因此可以透過給予想要的日期來瀏覽過去的新聞,這功能也剛好給我們爬取歷史新聞的機會。然而,在MoneyDJ 新聞摘錄這邊,只有用簡單的「頁面」來讓使用者瀏覽舊的新聞,這時候可以觀察看看「下一頁」甚至是第4,000頁也行,第2頁的網址會變成(http://blog.moneydj.com/news/page/2/);第4,000頁則是(http://blog.moneydj.com/news/page/4000/)。規律應該已經顯而易見了,只要我們基於上面的動作,再加一層迴圈,是否就有可能一口氣爬完4,000頁?
當然,1頁的新聞我們不必花費太多時間,然而4000多頁的新聞應該會花費不少時間。我們還在測試階段,只要先抓個2頁試試看就可以了,等到爬蟲程式沒有問題了再來考慮如何爬取所有資料,可以選擇分段進行或者一口氣做完都可以。
# 先創好一個空的data frame,準備合併所有資料
df.all <- data.frame()
# 令i為頁碼
for(i in 1:2) {
url <- paste0("http://blog.moneydj.com/news/", "page/", i)
doc <- read_html(url, encoding = "UTF-8")
header <- doc %>%
html_nodes(".entry-title.mh-loop-title") %>%
html_nodes("a") %>%
html_text()
link <- doc %>%
html_nodes(".entry-title.mh-loop-title") %>%
html_nodes("a") %>%
html_attr("href")
d <- doc %>%
html_nodes("span.mh-meta-date.updated") %>%
html_text()
article.page <- c()
for(i in 1:length(link)) {
doc.a <- read_html(link[i])
article <- doc.a %>%
html_nodes("div.entry-content.mh-clearfix") %>%
html_nodes("p") %>%
html_text() %>%
str_c(collapse = "")
article <- ifelse(str_length(article) < 10 || rlang:::is_empty(article), NA, article)
article.all <- append(article.all, article)
}
df <- data.frame(date = d, title = header, content = article.all) %>%
na.omit() %>%
mutate(date = as.character(date),
title = as.character(title),
content = as.character(content))
}
# 檢視一下data frame前面的內容
head(df, n = 1L)
## date title
## 1 2019-05-28 街口支付瘋狂行銷燒錢太快,今年兩度增資共 4 億元
## content
## 1 美國總統川普(Donald Trump)最新談話暗示中美貿易戰可能延長、中國則暗示要以稀土供應作反制(相關文章見此),引發避險需求升溫,美國10年期公債殖利率應聲下挫至2017年9月以來的新低點,跟3個月國庫券的殖利率相比出現倒掛情況。MarketWatch報價顯示,紐約債市28日尾盤時,對聯準會(Fed)利率決策較敏感的美國2年期公債殖利率下挫4.6個基點至2.129%,為2018年2月以來新低;10年期公債殖利率下挫6個基點至2.268%、創2017年9月以來新低;30年期公債殖利率下挫4.8個基點至2.706%,創2017年12月以來新低。(註:公債價格與殖利率呈現反向走勢。)殖利率曲線部分倒掛,暗示經濟恐陷衰退CNBC報導,摩根士丹利28日發表研究報告警告,美國股市及經濟展望都在惡化中,中美貿易關係趨於緊張、經濟數據又轉弱,讓美國企業獲利及經濟成長面臨風險。該證券指出,必須觀察經濟是否可能陷入衰退。報價顯示,美國3個月國庫券殖利率28日尾盤來到2.356%,高於10年期公債殖利率2.264%。3個月國庫券及10年期公債的殖利率曲線倒掛(即長債殖利率低於短債),被人們視為經濟衰退的可靠訊號,通常經濟會在警訊出現後、於一兩年內面臨衰退困境。避險需求湧入、降息預期增溫,帶動公債標售案買氣路透社、MarketWatch報導,美國財政部28日標售的810億美元2年期、5年期公債需求強勁,即便這兩種公債的殖利率已分別創下2018年2月、2017年12月以來的新低紀錄。其中,財政部標售的400億美元2年期公債,買氣為9個月以來最強,象徵買氣的認購比率(bid-to-cover ratio)多達2.75倍。新標售的410億美元5年期公債買氣也穩健,認購比例來到2.38倍、但略低於前一次標售時的2.44倍,需求不如2年債強健。美國財政部預計還將在29日標售320億美元公債。降息預期增溫。芝加哥商業交易所(CME)的FedWatch工具顯示,聯邦基金期貨投資人28日預測,聯準會(Fed)有80%的機率在12月底前降息一碼。義大利債務拉警報、提振避險需求義大利副總理薩爾維尼(Matteo Salvini)28日表示,歐洲執行委員會(European Commission;EC)可能會因該國債務、結構性赤字上升,違反歐盟規定,而對義國開罰30億歐元。薩爾維尼是極右派政黨「聯盟」(League)黨員,他誓言要「使盡全力」對抗過時且不公的歐盟財政規定。MarketWatch、CNBC報價顯示,義大利10年期公債殖利率28日尾盤應聲上揚3.3個基點至2.694%。德國10年期公債殖利率28日則下探-0.163%、創2016年9月30日以來新低。*編者按:本文僅供參考之用,並不構成要約、招攬或邀請、誘使、任何不論種類或形式之申述或訂立任何建議及推薦,讀者務請運用個人獨立思考能力,自行作出投資決定,如因相關建議招致損失,概與《精實財經媒體》、編者及作者無涉。MoneyDJ 新聞 2019-05-29 08:13:10 記者郭妍希 報導
近年來文字探勘的議題愈來愈受到重視,同樣身為沒什麼資源的研究生,只能自行摸索出爬蟲的方法來蒐集新聞資料,有了資料才有辦法進行後續的分析方法。總而言之,希望這篇文章能夠幫到有興趣的人,尤其是跟我一樣沒有資訊背景的大學生(或研究生),雖然目前關於R的中文文章、書籍已經不在少數,進入門檻還是沒有比較矮,我會盡量解釋每個步驟的意義以及R code主要的功能,期望能夠增加可讀性囉。