利用R语言爬取安居客中经纪人数据,并将结果导入msql数据库

1、背景

工作需要,需要获取安居客房地产相关数据;本文直接附上代码和注释。本文没有采用浏览器模拟抓取(参考之前文章),因为页面没那么复杂,不需要刻意用浏览器,并且用浏览器会降低速度。

2、代码

setwd('E:/study/code/RModeling')
library(XML)
library(RMySQL)#结果写进数据库需要
library(stringr)
#经纪人页面,其实直到115页即可,后面包括前面页面都有重复条目,后面会做去重
URL = paste0("https://dg.anjuke.com/tycoon/p",1:200)#115
links=c()
agent_id=c()
for (i in 1:length(URL)){
  #为防止封号,返回错误页面,必要的时间暂停还是需要的
  if(i %% 50==1){
    Sys.sleep(runif(1,1,2))
  }
  #获取和解析页面
  doc<-htmlParse(rawToChar(GET(URL[i])$content),encoding="UTF-8")
#获取链接
  link<-xpathSApply(rootNode,"//*[@id='list-content']/div/div[1]/div[1]/h3/a",xmlGetAttr,"href")
  #正则化提取经纪人id,作为唯一标识
  id=str_match(link,'[0-9]{6,8}')
  links=c(links,link)
  agent_id=c(agent_id,id)
}
#仔细分析会发现大量页面信息重复,需去重
links=unique(links)
agent_id=unique(agent_id)

#放入数据框
data=data.frame(links,agent_id,stringsAsFactors = FALSE)
for (i in 1:length(links)){
  #休息一下
  if(i %% 50==1){
    Sys.sleep(runif(1,1,2))
  }
  Sys.sleep(runif(1,0.01,0.2))
  #为防止被封号或者返回错误页面,再次循环
  tryCatch(
    {#先访问移动端页面
      url0=paste0('https://m.anjuke.com/dg/jjr-',agent_id[i])
      doc<-htmlParse(rawToChar(GET(url0)$content),encoding="UTF-8")
      rootNode<-xmlRoot(doc)

      #经纪人姓名
      data$agent_name[i]<-xpathSApply(rootNode,"//*[@id='header']/p[1]",xmlValue)
      #咨询回复率
      data$consult_rato[i]<-xpathSApply(rootNode,"/html/body/ul/li[2]/strong",xmlValue)
      #服务人数
      data$serve_num[i]<-xpathSApply(rootNode,"/html/body/ul/li[3]/strong",xmlValue)
      #服务范围
      tmp<-xpathSApply(rootNode,"/html/body/div[1]/ul",xmlValue)
      tryCatch(
        {#替换空值和换行符,这里用到了管道操作符%>%
          data$serve_tag[i]=gsub(" ","",tmp) %>% gsub("\n","-",.)   
          },
        error=function(e){data$serve_tag[i]<-'暂无'}
      )
      #所属公司
      data$company[i]<-xpathSApply(rootNode,"//*[@id='header']/p[2]/a[1]",xmlValue)
      #门店
      tmp<-xpathSApply(rootNode,"//*[@id='header']/p[2]/a[2]",xmlValue)
      tryCatch(
        {#使用管道操作符
          data$store[i]=gsub("\n","",tmp) %>% gsub(" ","",.) %>% gsub("/","",.)    
          },
        error=function(e){data$store[i]<-'暂无'},
        finally={print(i)}
      )

      #切换到PC端页面
      url1=paste0(links[i],'js')
      doc<-htmlParse(rawToChar(GET(url1)$content),encoding="UTF-8")
      rootNode<-xmlRoot(doc)

      #手机号码
      tryCatch(
        {
        data$tel[i]<-xpathSApply(rootNode,"/html/body/div[2]/div[2]/div/div[2]/div[1]/span",xmlValue)[1]
        },
        error=function(e){data$tel[i]<-'暂无'}
      )
      #主营板块
      tryCatch(
        {
          data$plate[i]<-xpathSApply(rootNode,"//*[@id='shop-content']/div[2]/div[1]/div[3]/div[4]/p/a",xmlValue)    
          },
        error=function(e){data$plate[i]<-'暂无'}
      )
      data$plate[i]<-xpathSApply(rootNode,"//*[@id='shop-content']/div[2]/div[1]/div[3]/div[4]/p/a",xmlValue)
      #主营小区
      tmp<-xpathSApply(rootNode,"//*[@id='shop-content']/div[2]/div[1]/div[3]/div[5]/p/a",xmlValue)
      data$xiaoqu[i]=str_c(tmp,collapse ='-')
      #佣金
      tryCatch(
        {
          data$commission[i]<-xpathSApply(rootNode,"/html/body/div[2]/div[2]/div/div[2]/div[1]/div/span[4]",xmlValue)
        },
        error=function(e){data$commission[i]<-'暂无'}
        )
      #房源评分
      data$house_score[i]<-xpathSApply(rootNode,"//*[@id='shop-content']/div[2]/div[1]/div[1]/div[3]/div/div/div/div[1]/span[1]/em",xmlValue)
      #服务评分
      data$serve_score[i]<-xpathSApply(rootNode,"//*[@id='shop-content']/div[2]/div[1]/div[1]/div[3]/div/div/div/div[2]/span[1]/em",xmlValue)
      #用户评分
      data$user_score[i]<-xpathSApply(rootNode,"//*[@id='shop-content']/div[2]/div[1]/div[1]/div[3]/div/div/div/div[3]/span[1]/em",xmlValue)
      #服务年限
      data$serve_age[i]<-xpathSApply(rootNode,"//*[@id='shop-content']/div[2]/div[1]/div[3]/div[3]/span",xmlValue)
      #从业经历
      tmp<-xpathSApply(rootNode,"//*[@id='shop-content']/div[2]/div[1]/div[3]/div[7]/div",xmlValue)
      data$experience[i]<-gsub(" ","",tmp) %>% gsub("\n",">",.)
      #创建时间
      data$created_date[i]<-format(Sys.time(), "%Y-%M-%d %X")
      #data$month[i]<-format(Sys.time(), "%Y-%M")
        },

    error=function(e){i<-i-1}
)
}

#链接MySQL数据库,用户名和密码根据自己设定修改
conn <- dbConnect(MySQL(), dbname = "test", username="root", password="***", host="localhost", port=3306)
#写如数据,不需要在MySQL里事先建表
dbWriteTable(conn, "agent", data,row.names = FALSE) 
#不过,我自己总是写不成功,提示编码问题,转换也没效果,只好先导到本地csv文件,再导入数据库,如下
write.csv(data, file = "tmp.csv", fileEncoding = "utf8", quote = FALSE, row.names = FALSE)
dbWriteTable(conn, value = "tmp.csv", name = "agent",append = TRUE, row.names = FALSE, sep = ",", quote='\"', eol="\r\n")
#这次成功

3、注意事项

代码处理中,多次使用t ryCatch函数,这里有两类作用。第一,也是最大的是因为,我在多次测试时发现即使我多次暂停也是会返回错误页面,但我重新加载发现页面是有数据的(可能是有一部分数据是从移动端页面的,会有提示下载app等错误页面),所以就将设置了i=i-1来循环加载。第二,是确实有些数据是没有的,比如,佣金等,所以在内部设置了,报错即等于“暂无”。相应在代码里已经注释了。下面贴出数据库里的数据结果
利用R语言爬取安居客中经纪人数据,并将结果导入msql数据库_第1张图片

你可能感兴趣的:(R语言,爬虫)