本文概述
当你需要进行网页抓取时, 通常可以使用Hadley Wickham的rvest软件包。该软件包提供了易于使用的开箱即用的解决方案, 以获取生成网页的html代码。但是, 当网站或网页使用JavaScript来显示你感兴趣的数据时, rvest软件包会缺少必需的功能。一种解决方案是使用PhantomJS。
(想练习将更多数据导入R吗?请尝试本教程。)
内容
- 加载必要的软件包
- 用R爬取JavaScript生成的数据
- 总结
加载必要的软件包
第一步, 你必须将分析所需的所有软件包都加载到工作空间中(如果尚未在本地系统上安装这些软件包, 请使用install.packages()使它们可用):
library(rvest)
library(stringr)
library(plyr)
library(dplyr)
library(ggvis)
library(knitr)
options(digits = 4)
用R爬取JavaScript生成的数据
下一步是使用PhantomJS收集TechStars数据。检查以下基本.js文件:
// scrape_techstars.js
var webPage = require('webpage');
var page = webPage.create();
var fs = require('fs');
var path = 'techstars.html'
page.open('http://www.techstars.com/companies/stats/', function (status) {
var content = page.content;
fs.write(path, content, 'w')
phantom.exit();
});
该脚本基本上在基础javascript代码完成其工作之后呈现HTML页面, 从而允许你获取其中包含所有表的HTML页面。为了在本分析的其余部分中停留在R中, 建议你使用system()函数来调用PhantomJS(你必须下载并安装PhantomJS并将其放在工作目录中):
# Let phantomJS scrape techstars, output is written to techstars.html
system("./phantomjs scrape_techstars.js")
经过一小段弯路后, 你最终在我们的本地系统上有了一个HTML文件techstars.html, 可以用rvest抓取。对Techstars网页的检查发现, 我们感兴趣的表位于具有CSS类批处理的div中:
batches <- html("techstars.html") %>%
html_nodes(".batch")
class(batches)
[1] "XMLNodeSet"
现在, 你有了XMLNodeSet对象的列表:每个对象都包含一个TechStars批处理的数据。在这里, 我们可以找到有关批次位置, 年份, 季节的信息, 还可以找到有关公司, 其当前总部, 当前状态以及所筹集资金总额的信息。我们不会在下面详细介绍数据收集和清理步骤;你可以自己执行代码并检查它们的完成情况。你会看到正在进行一些自定义清除, 以确保每一位信息的格式都正确:
batch_titles <- batches %>%
html_nodes(".batch_class") %>%
html_text()
batch_season <- str_extract(batch_titles, "(Fall|Spring|Winter|Summer)")
batch_year <- str_extract(batch_titles, "([[:digit:]]{4})")
# location info is everything in the batch title that is not year info or season info
batch_location <- sub("\\s+$", "", sub("([[:digit:]]{4})", "", sub("(Fall|Spring|Winter|Summer)", "", batch_titles)))
# create data frame with batch info.
batch_info <- data.frame(location = batch_location, year = batch_year, season = batch_season)
breakdown <- lapply(batches, function(x) {
company_info <- x %>% html_nodes(".parent")
companies_single_batch <- lapply(company_info, function(y){
as.list(gsub("\\[\\+\\]\\[\\-\\]\\s", "", y %>%
html_nodes("td") %>%
html_text()))
})
df <- data.frame(matrix(unlist(companies_single_batch), nrow=length(companies_single_batch), byrow=T, dimnames = list(NULL, c("company", "funding", "status", "hq"))))
return(df)
})
# Add batch info to breakdown
batch_info_extended <- batch_info[rep(seq_len(nrow(batch_info)), sapply(breakdown, nrow)), ]
breakdown_merged <- rbind.fill(breakdown)
# Merge all information
techstars <- tbl_df(cbind(breakdown_merged, batch_info_extended)) %>%
mutate(funding = as.numeric(gsub(", ", "", gsub("\\$", "", funding))))
结合了核心R, rvest, plyr和dplyr功能, 我们现在有了techstars数据框;所有TechStars公司的数据集, 其所有公开信息的格式都很好:
techstars
## Source: local data frame [535 x 7]
##
## company funding status hq location year season
## 1 Accountable 110000 Active Fort Worth, TX Austin 2013 Fall
## 2 Atlas 1180000 Active Austin, TX Austin 2013 Fall
## 3 Embrace 110000 Failed Austin, TX Austin 2013 Fall
## 4 Filament Labs 1490000 Active Austin, TX Austin 2013 Fall
## 5 Fosbury 300000 Active Austin, TX Austin 2013 Fall
## 6 Gone! 840000 Active San Francisco, CA Austin 2013 Fall
## 7 MarketVibe 110000 Acquired Austin, TX Austin 2013 Fall
## 8 Plum 1630000 Active Austin, TX Austin 2013 Fall
## 9 ProtoExchange 110000 Active Austin, TX Austin 2013 Fall
## 10 Testlio 1020000 Active Austin, TX Austin 2013 Fall
## .. ... ... ... ... ... ... ...
names(techstars)
## [1] "company" "funding" "status" "hq" "location" "year"
## [7] "season"
总结
通过上述工具和代码的组合, 我们设法从使用JavaScript脚本生成其数据的网站上抓取数据。可以看到, 这是一个结构化的过程, 一旦初始代码可用, 就可以轻松完成。是否想学习R, 并寻找数据科学以及R教程和课程?签出srcmini