对于一般的静态页面,我们在网页上单击鼠标右键,选择‘查看网页原代码’就能看到页面对应的html,相应的后台爬取的时候直接发个请求过去,处理返回来的页面数据筛选出我们想要的数据就可以了。
但是对于vue开发的页面,我们在网页上‘查看网页原代码’的时候,只能看到一堆css、js的引用,没有页面数据,爬取的时候如果还用之前的方法就不行了。还好有selenium包的存在帮我们解决了这个问题。
下面就是利用java程序,利用selenium包爬取js动态渲染网站的步骤:
1、准备一个和自己浏览器匹配的驱动
selenium是通过浏览器实现的js动态渲染,所以需要有个浏览器和匹配的驱动,我用的是chrome,这里有个淘宝镜像仓的chrome驱动下载地址:http://npm.taobao.org/mirrors/chromedriver/,注意版本一定要和浏览器的版本对应上,具体的对应关系可以百度。下载下来直接找个目录放着就行
2、pom文件里添加引用
<dependency>
<groupId>org.seleniumhq.selenium</groupId>
<artifactId>selenium-java</artifactId>
<version>2.33.0</version>
</dependency>
3、java代码
//驱动所在的地址
System.getProperties().setProperty("webdriver.chrome.driver", chromeDriverPath);
ChromeOptions option = new ChromeOptions(); //linux下chrome的启动参数
if(server.equals("linux")) {
System.out.println("linux模式启动");
option.addArguments("--headless"); //没有窗口的模式
option.addArguments("--no-sandbox"); //沙盒模式
option.addArguments("--disable-dev-shm-usage");
} //chrome.exe所在的地址
option.setBinary(chromePath);
ChromeDriver webDriver = new ChromeDriver(option); //请求根地址
webDriver.get(targetUrl); //页面信息
WebElement htmlElement = webDriver.findElement(By.xpath("/html")); //当前页句柄
String primaryHandle = webDriver.getWindowHandle(); //换页
Set<String> handles = webDriver.getWindowHandles();
for (String handel : handles) {
if(!handel.equals(primaryHandle)){
webDriver.switchTo().window(handel);
break;
}
}
另外selenium封装了很多定位元素的方法,通过WebElement的findElement方法一步步找到自己想要的数据就可以了。htmlElement就是我们在网页用f12看到的页面元素。
注意:
1、通过WebElement的选择器选择元素的时候,如果没有匹配到元素会报错,注意用try catch捕捉
2、在页面跳转等需要刷新页面的操作中,可能会有 明明元素存在,但是却获取不到或者点击事件失效的情况、或者debug模式正常,run模式报错的情况。这是由于页面没有充分渲染的原因,通过线程休眠Thread.sleep(300),可以大大减少这种情况发生的频率。