R语言从小木虫网页批量提取考研调剂信息

一、从URL读取并返回html树

    1.1 Rcurl包

        使用Rcurl包可以方便的向服务器发出请求,捕获URI,get 和 post 表单。比R socktet连接要提供更高水平的交互,并且支持 FTP/FTPS/TFTP,SSL/HTTPS,telnet 和cookies等。本文用到的函数是basicTextGatherer和getURL。想详细了解这个包的可以点击参考资料的链接。

R命令:

h <- basicTextGatherer( )   # 查看服务器返回的头信息
        txt <- getURL(url, headerfunction = h$update,.encoding="UTF-8...")  # 返回字符串形式html

参数url即为需要访问的url这里参数用headerfunction用到上一条命令返回的头信息,.encoding指定网页的编码方式为“UTF-8"。

网页的编码方式有很多,一般采用UTF-8,一些中文网页编码方式为“gbk",可以在浏览器的网页代码查看或者getURL返回的字符串看到。

小木虫网页代码查看

可见小木虫网页编码方式为gbk。

     1.2  XML包

       R语言XML包 具有读取或者创建XML(HTML)文件的功能,可以本地文件也支持HTTP 或者 FTP ,也提供Xpath(XML路径语言)解析方法。此处函数htmlparse,将文件解析为XML或者HTML树,便于进一步数据的提取或者编辑。

R命令:

htmlParse(file,asText=T,encoding="UTF-8"...) #参数file 即为XML或者HTML文件名或者text,asText参数是T指定file是text,encoding指定网页编码方式。

这里我们需要读取网页,并且拿到该网页的html树内容

自定义函数download,输入strURL,strURL为网址,返回html树内容

download <- function(strURL){
              h <- basicTextGatherer( )# 查看服务器返回的头信息
              txt <- getURL(strURL, headerfunction = h$update,.encoding="gbk") ## 字符串形式
               htmlParse(txt,asText=T,encoding="gbk")      #选择gbk进行网页的解析
             }

二、获得一个网页所有的URL

有时候我们需要进入每个网页上的子链接取分析数据,这个时候可以用到XML包的getHTMLLinks函数。

R命令:

getHTMLLinks(doc,  xpQuery = "//a/@href"...) #doc为解析后的HTML树文件,xpQuery指定想匹配的Xpath元素(下面会详细讲一点Xpath基础)。

此处我们需要获得小木虫“导师招生”页面下的所有话题链接。

    2.1 首先我们要获得导师招生的第一页,第二页,第三页,甚至到最后一页的网址。

导师招生首页

导师招生第二页,第三页。

发现首页网址是http://muchong.com/html/f430.html,余下的网址符合http://muchong.com/html/f430_  +   第几页   +.html

于是网址我们可以手动编辑。

strURLs="http://muchong.com/html/f430.html"

n=50

strURLs <- c(strURLs,paste(rep("http://muchong.com/html/f430_",n),c(2:n),".html",sep=""))

strURLs包括了所有1到50页导师招生网页的网址。

2.2获得每一页导师招生里面多个话题的链接

             

        在导师招生页面下,有许多话题,我们需要获得各个话题的链接。

用getHTMLLinks函数查看导师招生里面所有URL,再对比话题网址。

http://muchong.com/html/201702/11075436.html

发现话题网址是组成成分是http://muchong.com/ + html/201702/11075436.html 类似的URL

这时我采用先从导师招生网页提取所有URL,再匹配 html * .html格式的URL,最后再前面加上http://muchong.com/ 的策略。

自定义greg函数用于正则匹配,并且得到匹配到的字符串。
            greg <- function(pattern,istring){
                gregout <- gregexpr(pattern,istring)   #pattern为匹配模式,istring为待匹配的字符串
                substr(istring,gregout[[1]],gregout[[1]]+attr(gregout[[1]],‘match.length‘)-1)
             }

自定义extradress函数,用于提取strURL网页的中的 URL ,最后处理返回各个话题网页的链接。

extradress <- function(strURL){
                 prefix <- "http://muchong.com/"
                 pattern <- "html/[0-9/]+.html"
                 links <- getHTMLLinks(strURL)
                 needlinks <- gregexpr(pattern,links)
                 needlinkslist <- list()
                for (i in which(unlist(needlinks)>0)){
                    preadress <- substr(links[i],needlinks[[i]],needlinks[[i]]+attr(needlinks[[i]],‘match.length‘)-1)
                    needlinkslist<- c(needlinkslist,list(preadress))
                   adresses <- lapply(needlinkslist,function(x)paste(prefix,x,sep=""))
                 }
                return (adresses)
                 }

三、从HTML树中获得我们所要的数据

    3.1 XML文档基本知识

    下面是小木虫的部分html:


html为根元素,head和body是html的子元素,div是body的子元素,div有属性id,style,属性后面对应着属性值。“小木虫---“一行是p元素的文本内容。

    3.2 获得某个元素的内容

此处用到XML包中的getNodeSet函数,getNodeSet函数

R命令:

getNodeSet(doc, path...) #doc 就是html树文件对象,path 就是元素路径。可以用/从根元素一层层指定路径,也可以用//直接定位到某一层元素。

例如要定位到html下的body下的div,path 即为/html/body/div,也可//body/div直接从body开始定位。返回列表,如果定位到多个元素,将返回多个元素的列表。此次我们要定为到网页的话题内容:

我们这里直接定位到p元素,再从列表中筛选。

先输入命令

getNodeSet(doc,‘//p‘)

getNodeSet(doc,‘//p‘)[[2]]就是我们需要的内容。

但是返回的结果是个对象,要转变为字符串要用到函数xmlValue获得元素值。

xmlValue(x...) # x就是getNodeSet得到的对象

此处

  xmlValue(getNodeSet(a,‘//p‘)[[2]]) 得到我们所要的内容

  

   此时,我们获得了每一个话题的内容,我们就可以从内容中提取有效信息,是否招调剂,大学名,导师名字,研究方向,联系人,邮箱,电话等。

四、从小木虫获取调剂信息实例

我师妹是生物专业的需要调剂的学生,现在需要从小木虫网站提取别人发布的信息,做成一个表格形式,便于筛选查看和发送邮件。

以下是全部代码内容

library(RCurl)
library(XML)

download <- function(strURL){
    h <- basicTextGatherer()# 查看服务器返回的头信息
    txt <- getURL(strURL, headerfunction = h$update,.encoding="gbk") ## 字符串形式
    htmlParse(txt,asText=T,encoding="gbk")      #选择gbk进行网页的解析
}

extradress <- function(strURL){
  prefix <- "http://muchong.com/"
  pattern <- "html/[0-9/]+.html"
  links <- getHTMLLinks(strURL)
  needlinks <- gregexpr(pattern,links)
  needlinkslist <- list()
  for (i in which(unlist(needlinks)>0)){
    preadress <- substr(links[i],needlinks[[i]],needlinks[[i]]+attr(needlinks[[i]],‘match.length‘)-1)
    needlinkslist<- c(needlinkslist,list(preadress))
    adresses <- lapply(needlinkslist,function(x)paste(prefix,x,sep=""))
  }
  return (adresses)
}

gettopic <- function(doc){
    xmlValue(getNodeSet(doc,‘//p‘)[[2]])
}

greg <- function(pattern,istring){
    gregout <- gregexpr(pattern,istring)
    substr(istring,gregout[[1]],gregout[[1]]+attr(gregout[[1]],‘match.length‘)-1)
}

getinf <- function(topic){
pattern1 <- "招[\u4E00-\u9FA5]+[0-9-]*[\u4E00-\u9FA5]*[:、;,,;]*[\u4E00-\u9FA5]*[:、;,,;]*[\u4E00-\u9FA5]*[:、;,,;]*[\u4E00-\u9FA5]*[:、;,,;]*[\u4E00-\u9FA5]*(研究生)|(调剂)"
pattern2 <- "([\u4E00-\u9FA5]*课题组|[\u4E00-\u9FA5]*团队)"  
pattern21 <- "[\u4E00-\u9FA5]*[:、;,,;]*(教授|博士)"
pattern3 <- "[\u4E00-\u9FA5]*[:、;,,;]*[-A-Za-z0-9_.%]+@[-A-Za-z0-9_.%]+\\.[A-Za-z]+[.A-Za-z]*"
    #匹配@163.com类或者@abc.edu.cn两类邮箱
pattern4 <- "[\u4E00-\u9FA5]+老师"  #匹配某老师
pattern5 <- "[\u4E00-\u9FA5]*[::]*1[3,5,8]{1}[0-9]{1}[0-9]{8}|0[0-9]{2,3}-[0-9]{7,8}(-[0-9]{1,4})?" #匹配联系人和号码
pattern6 <- "(主|从事)*[\u4E00-\u9FA5]*(的研究|方向)为*[:、;,,;]*[\u4E00-\u9FA5]*"
pattern7 <- "[\u4E00-\u9FA5]+(大学|学院|研究院|研究所)"
pattern8 <-"[-A-Za-z0-9_.%]+@[-A-Za-z0-9_.%]+\\.[A-Za-z]+[.A-Za-z]*" #精确匹配邮箱

cate <- greg(pattern1,topic)
proj <- greg(pattern2,topic)
PI <- greg(pattern21,topic)
email <- greg(pattern3,topic)
man <- greg(pattern4,topic)
phone <- greg(pattern5,topic)
direc <- greg(pattern6,topic)
univ <- greg(pattern7,topic)
print(cate)
if (greg("(分子|生物|植物|细胞|医学|动物|水)+",topic) !=""){
    if (man =="" && proj != ""){
        man <- unlist(strsplit(proj,"课题组")[1])
    }
 
    if (email != ""){
      email <- greg(pattern10,email)
    }
    
    data.frame("类别"=cate,"大学"=univ,"课题"=proj,"PI"=PI,"联系人"=man,"邮箱"=email,"方向"=direc,"电话"=phone)
}
else{
  return("")
}
}

strURLs="http://muchong.com/html/f430.html"
n=50
dat <- data.frame("URL"="URL","类别"="类别","大学"="大学","课题"="课题","PI"="PI","联系人"="联系人","邮箱"="邮箱","方向"="方向","电话"="电话")
strURLs <- c(strURLs,paste(rep("http://muchong.com/html/f430_",n),c(2:n),".html",sep=""))
output1 <- "a2017.2.21.txt" #未处理数据,用于进一步处理
output2 <- "b2017.2.21.txt" #进一步筛选的数据,用于查看

for ( strURL in strURLs){
    adresses <- extradress(strURL)
    for (adress in adresses){
      message(adress)
      doc <- download(adress)
      topic <- gettopic(doc)
      inf <- getinf(topic)
      if (inf != ""){
        URL <- data.frame("URL"=adress)
        inf <- cbind(URL,inf)
        dat<- rbind(dat,inf)
      }
    }
}

write.table(dat, file = output, row.names = F, col.names=F,quote = F, sep="\t")  # tab 分隔的文件
message("完成!")

dat <- read.table(output1,sep="\t",header=T)
dat <- dat[dat$邮箱, ] #去除没有邮箱数据
dat <- dat[!duplicated(dat$邮箱), ]  #去除重复邮箱数据
dat$index <- as.numeric(rownames(dat))
dat <- dat[order(dat$index,decreasing=F),] #将乱序后的数据重新按照index排序
dat$index <- NULL
write.table(dat, file = output2, row.names = F, col.names=F,quote = F, sep="\t")  # tab 分隔的文件
message("完成!")

最后祝所有考研人都能成功被心仪的学校录取!

参考资料:

Rcurl包 :https://cran.r-project.org/web/packages/RCurl/RCurl.pdf

XML包:https://cran.r-project.org/web/packages/XML/XML.pdf

XML基本知识:http://www.cnblogs.com/thinkers-dym/p/4090840.html

时间: 2024-10-13 00:28:10

R语言从小木虫网页批量提取考研调剂信息的相关文章

R语言之RCurl实现文件批量下载

R语言之RCurl实现文件批量下载 前言: RCurl工具包的作者是由Duncan Temple Lang现任加州大学 U.C. Davis分校副教授.他曾致力于借助统计整合进行信息技术的探索.使用者通过RCurl可以轻易访问网页,进行相关数据的抓取以及下载,为数据分析提供原始素材.近年RCurl在数据分析业界中使用也越来越流行. Step1:安装RCurl install.packages('RCurl') Step2:代码实现 =========================== 1 #利

在R语言中显示美丽的数据摘要summary统计信息

原文链接:http://tecdat.cn/?p=6481 总结数据集 ## Skim summary statistics ## n obs: 150 ## n variables: 5 ## ## Variable type: factor ## variable missing complete n n_unique top_counts ## 1 Species 0 150 150 3 set: 50, ver: 50, vir: 50, NA: 0 ## ordered ## 1 FA

R语言中文社区历史文章整理(类型篇)

R语言中文社区历史文章整理(类型篇) R包: R语言交互式绘制杭州市地图:leafletCN包简介 clickpaste包介绍 igraph包快速上手 jiebaR,从入门到喜欢 Catterplots包,让你绘制不一样的图 今天再来谈谈REmap包 ggplot2你需要知道的都在这... R访问数据库管理系统(通过RODBC包和RMySQL包两种方式) NLP--自然语言处理(三)text2vec包 Rattle:数据挖掘的界面化操作 借助caret包实现特征选择的工作 R语言的高质量图形渲染

R语言实战-如何分析QQ群记录2-每日信息数量图

构思步骤: 1.从data中取出时间数据. 2.从时间数据中提取日期数据. 3.根据日期数据进行汇总每日的消息数量. 4.利用ggplot2进行绘图. #从data中获取时间信息 time<-data$dateTime #把时间中的日期属性提取出来 p<-paste(year(time),month(time),day(time),sep="-") #把p转换为数据框 Timed<-data.frame(p) #通过P分组,p段名称变成days,增加数量列Freq,根

批量提取视频文件信息(文件大小及时长)并统计

随着设备性能提高,视频文件越来越大了.服务器在对外提供视频服务时,需要承担越来越大的存储负担.一般提供1080P的AVC编码视频已满足多数观看需求.(1小时视频大约1.3G)此文要解决的就是关于已有大量高清视频(1小时超过6G)进行统计筛查. 通过python脚本统计指定目录(及其子目录)下视频文件的 大小.时长.压缩率(笔者先简单用大小除以时长),输出至excel.如此便可将压缩率较低的文件划分出来,导出处理.以减少磁盘存储负担. 源码详见https://github.com/chenfeng

R语言中批量安装软件包

R是一种开源软件,在编程的时候,需要安装很多软件包,如果一个一个的安装,那将费时费力.由于R支持脚本语言,所以考虑用.R文件存放所有要用的软件包,比如MASS.lpSolve.arules等,然后运行这个.R文件,就可以进行批量安装了. 1. 首先,将R语言中的软件包,按照它们的依存关系,保存在一个.R文件中,比如lib2D.R //lib2D.R install.packages("MASS") install.packages("lpSolve") instal

网页版批量提取目录下特定文件类型

功能: 这是一个网页版的文件批量提取特定目录下的某种类型的文件的功能. 初始化页面文本框中值为空,当输入完成确认后,文本框中数据不会发生变化,撤销也不会发生变化,点击清空按钮则全部清空. 主要思路: 1.文本框中的值用(String)session.getAttribute()来填充,第一次打开界面,用if语句来判断,显示空,跳转过来的就显示第一次输入的值. 2.ReceiveStartServlet.java,RevokeServlet.java,ClearServlet.java都跳转到起始

R语言︱文件读入、读出一些方法罗列(批量xlsx文件、数据库、文本txt、文件夹)

笔者寄语:小规模的读取数据的方法较为简单并且多样,但是,批量读取目前看到有以下几种方法:xlsx包.RODBC包.批量转化成csv后读入. R语言中还有一些其他较为普遍的读入,比如代码包,R文件,工作空间等. source  #读取R代码dget    #读取R文件load    #读取工作空间 -------------------------------- SPSS-STATA格式的读入包--foreign 读取其他软件的格式foreigninstall.packages("foreign&

约翰霍普金斯大学数据科学系列课程——R语言:提取子集

在R语言中,有下面三种操作符可以提取对象的子集: ? "["通常返回的对象与原对象的类型相同:它也可以返回一个对象中的多个元素 ? "[["用来从列表(list)或数据框(data.frame)中提取对象:也可从列表或数据框中提取单个元素,且返回对象的类型可以不为列表和数据框. ? "$"可以通过名称从列表和数据框中提取元素:如果仅从抽取元素的角度来看,和"[["没有区别 (1) 向量 向量可以使用"[]"