使用R和PhantomJS进行Web爬取

本文概述

当你需要进行网页抓取时, 通常可以使用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

微信公众号
手机浏览(小程序)
0
分享到:
没有账号? 忘记密码?