1.chrome headless简介
chrome headless是chrome浏览器的无界面模式,可以在不启用gui的情况下使用chrome浏览器的所有特性运行你的程序。这样更方便在Linux服务器上部署,同时可以方便用代码来操作浏览器,并且稳定性也有保证。使用chrome headless能够抓取很多需要登录的网站数据,甚至可以使用chrome获取cookie之后共享给其他的爬虫工具比如HttpClient ,OkHttp等。
2.开发环境
1.unbuntu18.04
2.jdk8
3.springboot
4.maven
5.selenium
3.环境搭建
-
chrome安装
sudo apt-get install libxss1 libappindicator1 libindicator7 wget https://dl.google.com/linux/direct/google-chrome-stable_current_amd64.deb sudo dpkg -i google-chrome*.deb # Might show "errors", fixed by next line sudo apt-get install -f
-
webdriver安装
在Ubuntu上下载最新的webdriver二进制包
wget https://chromedriver.storage.googleapis.com/2.45/chromedriver_linux64.zip
解压zip包
unzip chromedriver_linux64.zip
启动webdriver
./chromedriver -p 9515
效果如下
-
ssh端口转发
做ssh端口转发的原因是webdriver限制了只能本机应用才能调用,但是开发的时候是在自己的开发机上,需要远程连接webdriver,所以需要将webdriver的端口转发出来也就是需要把9515这个端口映射到自己的开发机上。命令如下:
ssh -L 9515:localhost:9515 bird@bird
在做端口映射之前需要让开发机能够免密登录,部署chrome 以及webdriver的服务器。
对ssh端口转发不懂得同学可以参考这篇文章
https://www.ibm.com/developerworks/cn/linux/l-cn-sshforward/
ssh免密登录很简单就不说了。
4.Java工程构建
- 标准的maven工程 主要依赖
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.12.RELEASE</version>
<relativePath/>
</parent>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
<version>1.1.10</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.44</version>
</dependency>
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>1.3.2</version>
</dependency>
<dependency>
<groupId>org.seleniumhq.selenium</groupId>
<artifactId>selenium-java</artifactId>
<version>2.48.1</version>
</dependency>
Tips:selenium最好使用2.4.x的版本,个人测试 chrome最新版75如果使用selenium3.x的话是会报错的
-
整合进springboot
@Configuration @Slf4j public class WebDriverConfig { @Value("${crawler.webdriver.remote.url}") private String webdriverUrl; public String getWebdriverUrl() { return webdriverUrl; } @Bean public RemoteWebDriver webDriver(){ ChromeOptions chromeOptions = new ChromeOptions(); chromeOptions.addArguments("--headless"); chromeOptions.addArguments("--disable-gpu"); DesiredCapabilities dc = DesiredCapabilities.chrome(); dc.setCapability(ChromeOptions.CAPABILITY, chromeOptions); try { RemoteWebDriver driver = new RemoteWebDriver(new URL(webdriverUrl),dc); return driver; } catch (MalformedURLException e) { log.error("构建webdriver失败:{}",e.getMessage()); return null; } } }
application.properties里面关于webdriver的配置
crawler.webdriver.remote.url=http://127.0.0.1:9515
-
爬虫的几个技巧
1.执行某一段Js脚本
driver.executeScript("document.getElementsByName(\"userid\")[0].value = '"+sevenEightGuaKaoConfig.getWebsiteUserName()+"';document.getElementsByName(\"userpwd\")[0].value = '"+sevenEightGuaKaoConfig.getWebsitePassword()+"';document.getElementsByName(\"log_submit\")[0].click();");
2.跳转到某个详情页并且将webdriver切换到新的tab页上
driver.executeScript("window.open('"+url+"');"); String[] newHandles=new String[driver.getWindowHandles().size()]; driver.getWindowHandles().toArray(newHandles); WebDriver resumeDetailDriver=driver.switchTo().window(newHandles[newHandles.length-1]);
3.关闭当前tab页并且将webdriver切换到跳转之前的tab页
Actions action = new Actions(resumeDetailDriver); action.keyDown(Keys.CONTROL).sendKeys("w").keyUp(Keys.CONTROL).sendKeys(Keys.NULL).perform();
4.获取访问到的页面
String pageSource = resumeDetailDriver.getPageSource();
5.某个区域截图
WebElement codePicWebelement = remoteWebDriver.findElement(By.id("Img")); File screenshot = ((TakesScreenshot)remoteWebDriver).getScreenshotAs(OutputType.FILE); BufferedImage fullImg = ImageIO.read(screenshot); Point point = codePicWebelement.getLocation(); int eleWidth = codePicWebelement.getSize().getWidth(); int eleHeight = codePicWebelement.getSize().getHeight(); BufferedImage eleScreenshot= fullImg.getSubimage(point.getX(), point.getY(),eleWidth, eleHeight); ImageIO.write(eleScreenshot, "png", screenshot);File screenshotLocation = new File("/Users/dudycoco/program/personal_pro/666jianzhuwang/img/yzm.png"); FileUtils.copyFile(screenshot, screenshotLocation);
5.后续
如果想通过chrome headless来做分布式爬虫,可以通过redis来管理url的队列。在实际使用的使用的时候,chrome headless完全可以当做页面的解析器用来提取数据,访问或者并发可以通过其他的框架来实现,比如webmagic,在写爬虫的时候还是要考虑失败之后的补偿,这个也是可以用Redis来做的。
chrome headless的作用不仅可以用来做爬虫,还可以用来做一些自动化测试的,这里就不展开了,感兴趣的同学可以自行谷歌TestNg,cumcuber。
在做爬虫的时候,还会涉及到一些图片识别的技术,可以去看看tess之类的技术,也可以来我的qq群,一起交流。
对Java python 爬虫或者数据分析感兴趣的同学可以进这个qq群:142067547一起交流学习。
网友评论