左手用R右手Python系列——动态网页抓取与selenium驱动浏览器
优采云 发布时间: 2022-05-08 01:30左手用R右手Python系列——动态网页抓取与selenium驱动浏览器
关于基础的网络数据抓取相关内容,本公众号已经做过很多次分享,特别是R语言的爬虫框架(RCurl+XML/httr+rvest[xml2+selectr])已经形成了较为丰富的教程系统。
但是所有这些都是基于静态页面的(抓包与API访问的除外),很多动态网页不提供API访问,这样就只能寄希望于selenium这种基于浏览器驱动技术来完成。
好在R语言中已经有了selenium接口包——RSelenium包,这为我们爬取动态网页提供了可能。我在今年年初写过一个实习僧网站的爬虫,那个是使用R语言中另一个基于selenium驱动的接口包——Rwebdriver来完成的。
当时技术不太成熟,思路也比较幼稚,我使用了导航器硬生生的遍历了500页内容,虽然最后也爬完了所有数据,但是耗时较长(将近40分钟),效率比较低。(感兴趣的小伙伴儿可以参考下上面那篇,不过实习僧的官网近期有较大改版,现在爬取难度肯定要比当初难多了!那个代码可能无法使用了)
最近抽时间学习了下RSelenium包的相关内容,这里感谢陈堰平老师在R语言上海大会现场所做《用RSelenium打造灵活强大的网络爬虫》的演讲,虽然未达现场,但是有幸看完视频版,其中的几个细节解决了我近段时间的一些困惑,这里表示感谢。
陈堰平老师主讲:《用RSelenium打造灵活强大的网络爬虫》
一个老外关于RSelenium的入门视频(youtobe请自行翻墙):
当前R语言中能做到解析动态网页的有以下几个包(欢迎补充):
本节以下内容正式分享今日案例,目标是拉勾网(不要问为什么,因为之前我还没有爬过拉钩)!
在介绍案例之前,请确保系统具备以下条件:
本地有selenium服务器并添加系统路径;
本地有plantomjs浏览器并添加系统路径;
安装了RSelenium包。
因为涉及到自动化点击操作,Chrome浏览器倒腾一下午硬是在点击环节出故障,找到了原因,因为拉勾网页面很长,而下一页按钮不在默认视窗范围内,使用了js脚本控制滑动条失败,原因不明,看到有人用firefox浏览器测试成功,我还没有试过,这里改用plantomjs无头浏览器(无需考虑元素是否被窗口遮挡的问题。)
R语言版:
#!!!这两句是在cmd后者PowerShell中运行的!<br />#RSelenium服务未关闭之前,请务必保持该窗口状态!<br />###启动selenium服务:
cd D:\
java -jar selenium-server-standalone-3.3.1.jar
##selenium服务器也可以直接在R语言中启动(无弹出窗口)<br />system("java -jar \"D:/selenium-server-standalone-2.53.1.jar\"",wait = FALSE,invisible = FALSE)
#加载包<br />library("RSelenium")<br />library("magrittr")<br />library("xml2")
启动服务
#给plantomjs浏览器伪装UserAgent<br />eCap % xml_text(trim=TRUE)
#职位所述行业
position.industry % read_html() %>% xml_find_all('//div[@class="industry"]') %>% xml_text(trim=TRUE) %>% gsub("[[:space:]\\u00a0]+|\\n", "",.)<br /> #职位福利
position.bonus % read_html() %>% xml_find_all('//div[@class="list_item_bot"]/div[@class="li_b_l"]') %>% xml_text(trim=TRUE) %>% gsub("[[:space:]\\u00a0]+|\\n", "/",.)<br /> #职位工作环境
position.environment% read_html() %>% xml_find_all('//div[@class="li_b_r"]') %>% xml_text(trim=TRUE)
#收集数据
mydata% xml_find_all('//div[@class="page-number"]/span[1]') %>% xml_text() !="30"){<br /> #如果页面未到尾部,则点击下一页
remDr$findElement('xpath','//div[@class="pager_container"]/a[last()]')$clickElement()<br /> #但因当前任务进度
cat(sprintf("第【%d】页抓取成功",i),sep = "\n")
} else {<br /> #如果页面到尾部则跳出while循环
break
}
}<br /> #跳出循环后关闭remDr服务窗口
remDr$close()
#但因全局任务状态(也即任务结束)
cat("all work is done!!!",sep = "\n")<br /> #返回最终数据
return(myresult)
}
运行抓取函数
<p>url