美文网首页
Java爬虫:chrome headless

Java爬虫:chrome headless

作者: dudycoco | 来源:发表于2019-01-30 22:13 被阅读102次
    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
      

      效果如下

    image-20190130213406787.png
    • 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一起交流学习。

    相关文章

      网友评论

          本文标题:Java爬虫:chrome headless

          本文链接:https://www.haomeiwen.com/subject/hzfhsqtx.html