上一篇文章Penroseasdf:R语言爬个”以xxx为开头写了个故事“的汇总 一开始单纯想看小……不,是复习一下rvest, 但是完全忘记知乎网页是用的AJAX动态加载技术(Asynchronous JavaScript and XML),即无需重新加载整个页面,只更新部分内容,以提升加载速度和用户体验。以知乎举例,每当页面被拉到底部或接近底部时,就可以看到滚动条又往上跳了,更多提问和回答又被加载出来(网速慢的时候会很明显)。
直接怒滚到加载完毕不失为一个方法,但是为了解放我们的双手,这次请出的是jsonlite包。AJAX技术是基于JavaScript的,比如说当页面拉到底部时,对应JavaScript就会运行,向网站服务器发出请求加载接下来的内容。一般来说这个过程中JSON object会被用来在客户端和服务器之前传递AJAX更新请求,其中就包含更新出来的内容。而jsonlite包能解决我们的问题,详情见
The jsonlite Package: A Practical and Consistent Mapping Between JSON Data and R Objects
好了,又到了喜闻乐见的爬虫部分,虽然还是“以X为开头写作”,但这次抓精华回答:
Step-1
打开目标网页,照例调出开发者工具,注意要在Network面板下,JSON文件一般会在XHR中。
Step-2
往下滚网页,让它加载几次,可以实时看到右边不断增加新的条目,这些都是加载获得的数据。点一下“essence?xxxxx"会弹出详细情况,找一找就会发现加载的网页数据都在里面;而"batch"中并没有我们要的东西,排除。
Step-3
右键点“essence?xxxxx" -> "Copy" -> "Copy link address", 得到link1。再点另一个以“essence?xxxx"开头的条目,得到link2。两个链接比较一下,会发现它们绝大部分是相同的(链接过长,为了保护眼睛比较的时候用了beyond compare),比如:
link1: https://www.zhihu.com/api/v4/topics/20049156[过长省略]&limit=10&offset=10
link2: https://www.zhihu.com/api/v4/topics/20049156[过长省略]&limit=10&offset=20
说明每次会加载出来10条回答。规律找出来接下来就好办了。
Step-4
这才算正式开始,首先把link中不变的部分拿出来,方便之后的循环
library(jsonlite)
library(dplyr)
baseurl <- "https://www.zhihu.com/api/v4/topics/20049156[过长省略]&limit=10&offset="
然后用fromJSON()尝试一下,看能不能提取出其中某个JSON文件中的信息:
mydata <- fromJSON(paste0(baseurl, 1, "0"), flatten=TRUE)
该有的都有了, 比如说问题题目(target.question.title), 问题ID,回答ID,等等。
Step-5
最后一步,loop起来,让R帮你retrieve data!
title <- "A"
questions <- data.frame()
links <- data.frame()
i <- 0
while (!is.null(title)) {
mydata <- fromJSON(paste0(baseurl, i, "0"), flatten=TRUE)
message("Retrieving page ", i)
#question title
title <- mydata[["data"]][["target.question.title"]]
questions <- rbind(questions, as.data.frame(title))
#question links
questionID <- mydata[["data"]][["target.question.id"]]
answerID <- mydata[["data"]][["target.id"]]
questionURL <- purrr::map2(questionID, answerID, ~ paste0("https://www.zhihu.com/question/",.x,"/answer/",.y))
questionURL <- do.call(rbind,questionURL)
links <- rbind(links, questionURL)
i <- i+1
}
#combine
finalout <- cbind(questions,links)
最后retrieve了一百页整,换手动滚的话……。
最后所得因为内容太多就不放在这了,想看的去下面找哦
Penroseasdf:⛲汇总 |『以 X 为开头写作』精华回答zhuanlan.zhihu.com参考资料
- ajax(Ajax 开发)_百度百科
- JSON with Ajax - Tutorialspoint
- Combining pages of JSON data with jsonlite