记录使用Selenium抓取前端渲染数据
这几天准备用程序抓下一个网站的数据, 具体哪个就不说了, 为了减少人工劳动, 省点力气。用到的技术 Java, Selenium, chromeDriver, 系统ubuntu16.04
开始查看了网站的源码, 看到网站使用的模板的方式,
<% for(var i=0; i < loop_times; i++) { %>
<% var items = rider_list.slice(i * num_per_line, (i+1) * num_per_line); %>
<tr>
<% for (var j=0; j < items.length; j++) { %>
<%
这样直接抓取html是无法拿到数据的,页面展示的内容是经过浏览器渲染过之后的结果, so。。。, 需要使用浏览器把拉下的源码执行js脚本,前端渲染出页面, 再使用xpath 解析数据。
Selenium可以通过WebDriver调用Chrome 、Firefox 、Safari 等浏览器。
WebDriver 支持以下的
- ChromeDriver
- EventFiringWebDriver
- FirefoxDriver
- HtmlUnitDriver
- InternetExplorerDriver
- PhantomJSDriver
- RemoteWebDriver
- SafariDriver
chromeDriver 下载地址: https://sites.google.com/a/chromium.org/chromedriver/downloads ,注意版本支持情况, 我用的是最新的版本2.37
Latest Release: ChromeDriver 2.37
Supports Chrome v64-66
安装 Google Chrome 这里我们选择的是 google-chrome-stable 版本:
$ wget -q -O - https://dl-ssl.google.com/linux/linux_signing_key.pub | sudo apt-key add -
$ sudo sh -c 'echo "deb [arch=amd64] http://dl.google.com/linux/chrome/deb/ stable main" >> /etc/apt/sources.list.d/google.list'
sudo apt-get update
sudo apt-get install google-chrome-stable
测试chromeDriver 是是否正常运行, 最初阿里云的ECS安装的是centos6.8 的系统, 安装完linux chrome, 运行chromeDriver的时候,遇到各种库找不到,根据提示一直装下去, 还是问题不断, 谷哥发现说centos 对chrome 支持不太好(没有继续跟踪原因, 有懂的朋友给明示一下,多谢), 换成ubuntu 16.04, 测试正常
root@iZj6c1imv6wpn7tfmm7nusZ:/work/fantasy# ./chromedriver
Starting ChromeDriver 2.37.544315 (730aa6a5fdba159ac9f4c1e8cbc59bf1b5ce12b7) on port 9515
Only local connections are allowed.
抓取页面的java代码, 使用chromeDriver 渲染后可以正常的使用 xpath, 查找html元素了, 基础的用法就是使用By 的查找方式了, 可以按id, class, tag等等查找
这里有几个点需要注意
ChromeOptions options = new ChromeOptions();
options.addArguments("--headless");
options.addArguments("--disable-gpu");
options.addArguments("--no-sandbox");
option 需要设置,
- headless Chrome指在headless模式下运行谷歌浏览器。本质就是不用谷歌运行谷歌!它将由Chromium和Blink渲染引擎提供的所有现代网页平台的特征都转化成了命令行。 必须在59以后可以使用
- disable-gpu, 服务器很多没有gpu, 禁用掉,防止出错
- no-sandbox 取消沙盒模式, 在root用户下, 必须加上此选项
准备工作已做好, 可以抓到数据了, 摆脱人工定时查看, 可以使用bearychat ,出现需要通知的给自己或者团队发送消息通知, 做幸福的程序员
java 抓取分析代码
private WebDriver webDriver;
public XXXSpider() {
String driver = System.getProperty("webdriver.chrome.driver");
if (driver == null) {
logger.info("没有设置 driver 变量");
System.getProperties().setProperty("webdriver.chrome.driver", "/Users/chengpanwang/Downloads/chromedriver");
} else {
logger.info("driver: {}", driver);
}
}
public BigDecimal pageDetail(String url) {
logger.info("详情页: {}", url);
........
try {
ChromeOptions options = new ChromeOptions();
options.addArguments("--headless");
options.addArguments("--disable-gpu");
options.addArguments("--no-sandbox");
webDriver = new ChromeDriver(options);
webDriver.get(url);
WebElement webElement = webDriver.findElement(By.xpath("/html"));
WebElement roleSkill = webElement.findElement(By.id("role_skill"));
logger.info(roleSkill.getText());
logger.info("选中技术标签");
roleSkill.click();
WebElement skillTb = webElement.findElement(By.className("skillTb"));
for (WebElement item : skillTb.findElements(By.tagName("td"))) {
String level = item.findElement(By.tagName("p")).getText();
String h5 = item.findElement(By.tagName("h5")).getText();
.... 具体业务代码
}
webDriver.close();
} catch (Exception e) {
logger.error("", e);
}
return price;
}