什麼是爬蟲

爬蟲流程

實作方式

觀察網頁

github.png

檢查網頁元素

github_inspect.png

造訪網頁取得內容

使用httr套件

library(httr)
url = "https://github.com/dboyliao/DSC2015_RBasic"
response = GET(url)
content = content(response)
capture.output(content)[1:5] # Capture first 20 lines of output
[1] "<!DOCTYPE html>"                                                                                                                                                        
[2] "<html lang=\"en\" class=\"\">"                                                                                                                                          
[3] "<head prefix=\"og: http://ogp.me/ns# fb: http://ogp.me/ns/fb# object: http://ogp.me/ns/object# article: http://ogp.me/ns/article# profile: http://ogp.me/ns/profile#\">"
[4] "<meta charset=\"utf-8\">"                                                                                                                                               
[5] "<meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\">"                                                                                                              

剖析資料

針對不同資料格式要選不一樣的剖析套件。以html檔案為例,使用CSS選擇器來剖析。

library(XML)
library(selectr)
nodes = querySelectorAll(content,".files .content a")
nodes
## [[1]]
## <a href="/dboyliao/DSC2015_RBasic/tree/master/DSC2015" class="js-directory-link js-navigation-open" id="85110664b2e3419869c3e238b643b754-aa21898809ee549f307bd1ebbda664142f0643ed" title="DSC2015">DSC2015</a> 
## 
## [[2]]
## <a href="/dboyliao/DSC2015_RBasic/tree/master/slides" class="js-directory-link js-navigation-open" id="f4d5c52946e476c66dfc36433c82aa78-80a9d6a9a82b93edc4ee48a490de2718e723780a" title="slides">slides</a> 
## 
## [[3]]
## <a href="/dboyliao/DSC2015_RBasic/blob/master/.gitignore" class="js-directory-link js-navigation-open" id="a084b794bc0759e7a6b77810e01874f2-2065e6d4cc27613d71d470bbc7bd7e3f5ee537a0" title=".gitignore">.gitignore</a> 
## 
## [[4]]
## <a href="/dboyliao/DSC2015_RBasic/blob/master/RBasic1.R" class="js-directory-link js-navigation-open" id="b232b3fb3a8cbf459c8344ec15365d24-c3c27450020f45945a0da10c98292f416ddfb3f9" title="RBasic1.R">RBasic1.R</a> 
## 
## [[5]]
## <a href="/dboyliao/DSC2015_RBasic/blob/master/working_script.R" class="js-directory-link js-navigation-open" id="1b3222ae4437d042ae6c959d0d998ab2-43be8ced685f462fec4f070be5a50413bcea5971" title="working_script.R">working_script.R</a> 
## 
## attr(,"class")
## [1] "XMLNodeSet"

取出字串

xmlValue(nodes[[1]])
## [1] "DSC2015"

範例欣賞

新北市消防局API http://hackersome.com/p/faryne/ntpcfd-stats

參數 意義 格式、範例
service_time 出勤日期 格式為 YYYY-mm-dd
service_unit[] 出勤分隊 例如 樹林分隊 、 板橋分隊
service_type[] 出勤任務類型 目前只能輸入 救護、火災 、 災害
  • 更新:颱風之後就壞了,8/8以後會無資料

新北市消防局

  • 回傳結果:
    • service_type:出勤任務類型
    • service_unit:出勤分隊
    • service_addr:出勤地址
    • service_time:報案時間
    • lat:出勤地址約略緯度
    • lng:出勤地址約略經度
  • 備註:若不帶入任何參數,則取出當天所有報案紀錄。
  • 資料來源:http://epaper.tpf.gov.tw/liveview/default.asp

造訪網頁取得內容 + 剖析資料

library(jsonlite)
library(knitr)

url = "http://ha2.tw/ntpcfd/api/json?service_time=2015-07-25"
data = jsonlite::fromJSON(url)
kable(head(data))
service_type service_unit service_addr service_time lat lng
災害 蘆洲分隊 新北市蘆洲區三民路 2015-07-25 00:00:00 25.089419500 121.468358900
災害 中和分隊 新北市中和區中和路 2015-07-25 00:13:00 24.999690800 121.505932400
災害 蘆洲分隊 新北市蘆洲區永平街 永樂街38巷交叉路 2015-07-25 00:13:00 25.091188200 121.458256100
災害 裕民分隊 新北市新莊區民安西路88巷1弄 2015-07-25 00:14:00 25.019213600 121.426440000
災害 德音分隊 新北市泰山區泰林路二段 2015-07-25 00:16:00 25.060163500 121.434021400
災害 新店分隊 新北市新店區中興路三段 2015-07-25 00:19:00 24.981748900 121.543918800

檢視資料

kable(summary(data), align = "l")
service_type service_unit service_addr service_time lat lng
Length:490 Length:490 Length:490 Length:490 Length:490 Length:490
Class :character Class :character Class :character Class :character Class :character Class :character
Mode :character Mode :character Mode :character Mode :character Mode :character Mode :character

預處理

data$service_type = as.factor(data$service_type)
data$service_unit = as.factor(data$service_unit)
data$lat = as.numeric(data$lat)
data$lng = as.numeric(data$lng)
dataWithGeoPoint = data[ data$lng>0, ]
kable(summary(dataWithGeoPoint), align = "l")
service_type service_unit service_addr service_time lat lng
災害:486 淡水分隊: 26 Length:486 Length:486 Min. :24.91 Min. :121.3
NA 南勢分隊: 21 Class :character Class :character 1st Qu.:25.00 1st Qu.:121.4
NA 新店分隊: 18 Mode :character Mode :character Median :25.02 Median :121.5
NA 三重分隊: 17 NA NA Mean :25.04 Mean :121.5
NA 重陽分隊: 17 NA NA 3rd Qu.:25.07 3rd Qu.:121.5
NA 莒光分隊: 16 NA NA Max. :25.26 Max. :122.0
NA (Other) :371 NA NA NA NA

簡單視覺化

library(ggplot2)
library(ggmap)

box = make_bbox(dataWithGeoPoint$lng, dataWithGeoPoint$lat) 
p = ggmap(get_map(box, maptype = "toner", zoom = 11)) 
q = p + geom_point(data=dataWithGeoPoint, aes(lng, lat, colour="red" ), size =3)+ theme(legend.position="none")
q