我知道大家對程式語言沒興趣,所以我先講怎樣看圖:
- 每個圈圈代表一個網友,圈圈的大小代表該網友被“不同人”推文的文章次數
- 箭頭代表的推文的方向 A -> B表示A推B的文章,而且不同大小的圈圈
從圖中來看,可以發現網友之間的互動真的非常密切和多樣,除了幾位人氣王之外,也有很多小團體和出現眾星拱月的情況.人氣王彼此之間的互動也不在少數,相信有逛過wanted版的朋友看起來會更有感觸.至於ID的部分我就隱藏起來了,雖然是這是公開資料,但是畢竟不是每個人都喜歡被別人分析XD
以下講的是做法:本次分析包含資料截取到畫圖都是利用R軟體來實做,用的主要方法包括爬網和社群網絡分析(social network analysis),以下是原始碼:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
library("XML") | |
library("httr") | |
library("stringr") | |
library("igraph") | |
library("dplyr") | |
##這部分是爬網,先從網頁版PTT中抓下每篇文章的聯結 | |
rm(data) | |
data <- list() | |
for( i in 1628:2628){ | |
url <- paste('bbs/Wanted/index', i, '.html', sep='') | |
html <- content(GET("https://www.ptt.cc/", path = url),as = 'parsed') | |
url.list <- xpathSApply(html, "//div[@class='title']/a[@href]", xmlAttrs) | |
data <- rbind(data, url.list[[1]]) | |
} | |
##把一些空值刪掉 | |
data = Filter(function(x) x != "www.ptt.cc",data) | |
##根據每篇文章代碼進去抓作者和推文的資料 | |
popu <- function(link){ | |
html <- content(GET('https://www.ptt.cc', path = data[[link]]), as = 'parsed') | |
poster <- xpathApply(html,"//div[@class='article-metaline']/span[@class='article-meta-value']",xmlValue)[[1]] | |
#這邊特別說明一下,因為作者這個欄位很討厭,除了ID之外還有暱稱,要把暱稱刪掉 | |
poster <- str_split_fixed(poster, "\\(",2)[,1] | |
puller <- xpathApply(html,"//div[@class='push']/span[@class='f3 hl push-userid']",xmlValue) | |
#這個if是排除那些沒人有推文的作者(例如我) | |
if (length(puller) >0 ){ | |
puller <- as.data.frame(matrix(unlist(puller),nrow = length(puller),T)) | |
edgelist <- merge(poster,puller,all = TRUE) | |
return (edgelist) | |
} | |
} | |
##我在這個步驟卡了半天 每次抓ID和推文都很容易抓漏 | |
##原本用sapply做但是遇到抓錯後面就全部錯,所以改用for回圈 | |
edge = list() | |
for (l in 1:length(data)){ | |
edge <- rbind(edge, popu(l)) | |
} | |
#依照推文和被推者分組,計算每個pair的數量 | |
edge2 <- group_by(edge,x,V1) | |
edge2 <- summarise(edge2,weight=n()) | |
#from 表示推文者 in 表示被推文的 | |
edge2 <- data.frame(from = edge2$V1, to = edge2$x,weight = edge2$weight) | |
#使用igraph套件將edge list的data轉成graph 物件,這是有方向性的 | |
g <- graph.data.frame(edge2,directed = TRUE) | |
#用被推文的數量“in"來決定大小 | |
V(g)$size <- degree(g,mode = ("in"))/2 | |
#接下來就是畫圖輸出了 | |
png(filename="org_network.png", height=1080, width=1080) | |
plot(g, layout = layout.fruchterman.reingold, | |
vertex.label=NA, | |
edge.arrow.size = 1 | |
) | |
dev.off() | |
作者已經移除這則留言。
回覆刪除作者已經移除這則留言。
回覆刪除歡迎轉貼~請註明來源
刪除您好:
回覆刪除請問一下抓網址那邊為什麼i只放數字,但實際上不是還會夾雜英文嗎?
如:/bbs/Wanted/M.1446388368.A.CB2.html
我剛剛也試了直接在網址(https://www.ptt.cc/bbs/Wanted/index.html)中的index後加數字
看起來是日期的不同???
會另外去讀取每一頁中的文章代碼
刪除作者已經移除這則留言。
刪除