在做图片爬虫时,经常会遇到一些网站需要鼠标不断滚动网页才会继续响应,这对传统的HttpClient是一件很困难的事情,至少我不知道如何处理。幸好,我找到了Selenium。
Selenium
Selenium 是一组软件工具集,每一个都有不同的方法来支持测试自动化。大多数使用 Selenium 的QA工程师只关注一两个最能满足他们的项目需求的工具上。然而,学习所有的工具你将有更多选择来解决不同类型的测试自动化问题。这一整套工具具备丰富的测试功能,很好的契合了测试各种类型的网站应用的需要。这些操作非常灵活,有多种选择来定位 UI 元素,同时将预期的测试结果和实际的行为进行比较。Selenium 一个最关键的特性是支持在多浏览器平台上进行测试。
在build.gradle中添加依赖:
compile 'org.seleniumhq.selenium:selenium-java:3.7.1'
除了需要添加selenium的依赖之外,还需要添加webdirver。
在这里,我使用chromedirver(也可以选择firefoxdriver,看个人喜好),chromedirver可以在https://sites.google.com/a/chromium.org/chromedriver/downloads 下载最新的版本。针对不同的操作系统,需要下载对应的版本。
PicCrawler
PicCrawler是我开发的抓取图片的爬虫,支持一些简单的定制比如User-Agent、referer、header、cookies等。感兴趣的同学可以看我之前写的文章基于RxJava2实现的简单图片爬虫
对于Java项目如果使用gradle构建,由于默认不是使用jcenter,需要在相应module的build.gradle中配置
repositories {
mavenCentral()
jcenter()
}
然后再添加最新的piccrawler的依赖
compile 'com.cv4j.piccrawler:crawler:0.5.1'
具体实现
1. 配置chromedriver的路径
static {
System.setProperty("webdriver.chrome.driver", "crawler-selenium/chromedriver");
}
2.下载某个网页的图片
public void downloadPic(String url) {
WebDriver driver = new ChromeDriver();
driver.get(url);
String html = driver.getPageSource();
List<String> urls = parseHtmlToImages(html,picParser);
crawlerClient.downloadPics(urls);
}
在这里,通过WebDriver请求网页,然后将请求的html字符串进行解析得到图片的集合,最后交给图片爬虫进行下载图片。
3.多次滚动某个网页,下载网页上的图片
/**
*
* @param url
* @param scrollDownNum 模拟鼠标滚动到屏幕底部到次数
*/
public void downloadPic(String url,int scrollDownNum) {
WebDriver driver = new ChromeDriver();
driver.get(url);
String html = driver.getPageSource();
List<String> urls = parseHtmlToImages(html,picParser);
crawlerClient.downloadPics(urls);
if (scrollDownNum>1) {
for (int i=0;i<scrollDownNum-1;i++) {
Utils.scrollDown(driver);
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
html = driver.getPageSource();
urls = parseHtmlToImages(html,picParser);
crawlerClient.downloadPics(urls);
}
}
}
在这个方法里用到了scrollDown(),它的作用是模拟浏览器向下滚动。
/**
* 模拟浏览器向下滚动
* @param driver
*/
public static void scrollDown(WebDriver driver) {
JavascriptExecutor js = (JavascriptExecutor)driver;
js.executeScript("scrollTo(0,10000)");
}
带scrollDownNum参数的downloadPic(),第一次先通过WebDriver请求网页,然后不断地模拟浏览器行为向下滚动不断地请求网页,并解析网页下载图片。scrollDownNum表示向下滚动的次数。
测试
对开发者头条网站上的图片进行抓取,并模拟浏览器向下滚动3次。
public static void main(String[] args) {
SeleniumCrawlerClient client = new SeleniumCrawlerClient();
client.downloadPic("https://toutiao.io/",3);
}
程序执行后,会弹出一个Chrome,由Selenium进行控制。毕竟Selenium是自动化测试的工具:)
图片抓取完毕。
再换一个网站尝试一下,对简书的个人主页上的图片进行抓取。
public static void main(String[] args) {
SeleniumCrawlerClient client = new SeleniumCrawlerClient();
client.downloadPic("//www.greatytc.com/u/4f2c483c12d8",3);
}
同样能达到一样的效果,那我就可以放心去抓其他网站上的图片了:)
总结
具体的代码可以查看这个文件。
由于selenium需要依赖webdriver,而webdriver本身比较大又跟操作系统相关,所以没有把它封装成一个库。我也是第一次尝试使用selenium,未来希望能够结合它能够做出更好玩的东西。
最后,附上github地址:
https://github.com/fengzhizi715/PicCrawler