栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

基于Java + selenium 爬取某网站千张图片

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

基于Java + selenium 爬取某网站千张图片

预览(可以根据循环次数爬取大量图片)

 

一、网页分析 1

点击F12进入检查,将小箭头移到网页中随便一张图片上

2

进一步我们可以发现每一张图片的链接都包含在

    标签的子标签
  • 3

    图片的url也可以在

  • 中获得,但是在这里获得到的图片url并不是高清的,图中二哈的图片仅有30kb

    4

    所以再进一步在中找到该链接能获取高清版本的图片,点击进入该图片的详情页面,可以找到一标签,其中src后边的链接就是高清版本的图片。

    5、总结

    网页分析中我们要获得两个url,第一个是在百度图片首页上找到中标签href后边的链接;第二个是进入第一个链接后找到标签,获取src后的链接,即图片的高清版本的链接。

    二、selenium导入&添加驱动 1、通过maven
       
         org.seleniumhq.selenium
         selenium-java
         3.141.59
       
    2、通过jar包直接导入

    到selenium官网下载想要使用的版本(我用的是3.141.59),然后打开idea,点开File,找到Project Structure点击

    将刚刚下载的selenium jar 包直接添加上就OK了。

    3、添加驱动

    我们需要下载selenium和浏览器及对应浏览器驱动,下面以下载chrome和chromedriver为例。

    谷歌浏览器驱动安装:https://npm.taobao.org/mirrors/chromedriver?spm=a2c6h.14029880.0.0.735975d7jW7LC2

    安装版本与自己浏览器对应的版本要一样,下载目录一般是与浏览器的相同目录下。

    三、最喜欢的编程阶段 1、两个重要的集合

    首先要声明两个List集合用来保存我们从网页上获取到的两个url

    //保存第一层链接,称外部链接
       private List outUrlList ;
       //保存图片链接
       private List picUrlList;
    2、利用selenium自动化搜索某类型图片

    以二哈为例

     
    public void getOutUrl(String url,String word) throws Exception{
           //设置不显示浏览器页面
           ChromeOptions chromeOptions=new ChromeOptions();
           chromeOptions.addArguments("-headless");
    
        //创建浏览器驱动对象
           WebDriver driver = new ChromeDriver(chromeOptions);
           driver.manage().window().maximize();
           driver.get(url);
    
          driver.findElement(By.id("kw")).sendKeys(word);//word在这就能设置成“二哈”。
           driver.findElement(By.className("s_btn_wr")).click();
        ····
             
    //最后要将浏览器驱动退出
           driver.quit();
    }
    3、获取外部链接

    找到网页上所有,直接获取我们想要图片详情页

    //返回一个webElement的List集合
    List webEList = driver.findElements(By.className("imgbox-border"));
    //通过该元素集合进行foreach循环找到标签,添加href到outUrlList集合中
    for(WebElement outUrl : webList){
       String furtherUrl = outUrl.fingElement(By.tagName("a")).getAttribute("href");
       outUrlList.add(furtherUrl);
    }

    这样一来我们就将网页上出现的所有图片详情页获得到了

    3、获取高清图片url

    public void getPicUrl(List outUrlList){
           //设置不显示浏览器页面
           ChromeOptions chromeOptions=new ChromeOptions();
           chromeOptions.addArguments("-headless");
           WebDriver driver = new ChromeDriver(chromeOptions);
    
           //通过for循环将外部链接自动化打开,然后找到我们要的元素(高清图片链接),添加到picUrlList中
           for (i = 0;i 
    4、下载图片 
    

    这个阶段还要用到IO流和网络编程的知识,不过很简单。

    public void downtown(List picUrlList,String picSrc){
    //设置图片排号
           int i = 0;
       
           //判断picSrc存不存在,不存在接得先建立
           File file = new File(picSrc);
           if(!file.exists()){
          file.mkdirs();
          }
           //输入输出流
           InputStream in = null;
           FileOutputStream fos = null;
       
           //循环下载
           for(String picUrl : picUrlList){
               try{
                   //一般下载图片的流程是这样固定不变的,比较简单
                  System.out.println("正在下载:"+picUrl);
                  byte[] bytes = new byte[1024];
             
                   in = new URL(picUrl).openConnection().getInputStream();
                   fos = new FileOutputStream(path+"\"+i+++".jpg");
               
                   int readLine = 0;
                   while ((readLine = in.read(bytes))!=-1){
                      fos.write(bytes,0,readLine);
                   }
             
                   System.out.println("第" + i + "张图片下载完成");
                  }catch(Exception e){
                       e.printStackTrace();
                   }finally{
               //最后要记得关闭输入输出流
               try {
                       fos.flush();
                  } catch (IOException e) {
                        e.printStackTrace();
                   }
               
               try {
                        fos.close();
                  } catch (IOException e) {
                       e.printStackTrace();
              }
               
               try {
                       in.close();
                  } catch (IOException e) {
                       e.printStackTrace();
              }
          }
      }
    }
    四、编程过程中我遇到的问题 1、图片不够多

    由于selenium这个框架是实时地模仿浏览器操作的,百度图片加载的时候是一种ajax机制(局部刷新),所以我在获取第一个链接的时候会加上这么一段代码,用来获取更多的图片。

    //每隔0.5秒模仿浏览器滚动上下进度条,让程序能够加载网页
        Thread.sleep(400);
        for (int i = 0; i <8 ; i++) {
           ((JavascriptExecutor) driver).executescript("window.scrollTo(0.5,document.body.scrollHeight)");
           Thread.sleep(500);
        }
        Thread.sleep(1000);
    2、总是抛no such element 异常

    这个异常其实也很容易找到原因,点开百度图片的首页就能知道了

    一般查询的图片,前边几张都是广告,那就没有我们要的元素在它的中,如下图所示,标签中是空的

    然而selenium框架并没有可以判断元素是否存在的方法,我们就得自己写

    //判断元素是否存在方法,用浏览器驱动查找
           public Boolean isElemExist(WebDriver driver,By seletor) {
               try {
                   driver.findElement(seletor);
    
                   return true;
               } catch (Exception e) {
    //             TODO: handle exception
                   return false;
              }
          }
       //方法重写,用元素查找
           public Boolean isElemExist(WebElement element,By seletor) {
               try {
                   element.findElement(seletor);
                   return true;
              } catch (Exception e) {
    //             TODO: handle exception
                   return false;
              }
          }

    方法调用实例:

    //在获取外部元素时调用,如果没有含标签的元素就跳过
        for (WebElement outUrl : webEList) {
           if(isElemExist(outUrl,By.cssSelector(".imgbox-border>a"))){
               String furtherUrl = outUrl.findElement(By.tagName("a")).getAttribute("href");
               outUrlList.add(furtherUrl);
           }else{
               continue;
          }
        }
    //在获取高清图片链接时调用,没有高清版本链接就跳过。
    ····
        if(isElemExist(driver,By.id("hdFirstImgObj"))){
           picUrl = driver.findElement(By.id("hdFirstImgObj")).getAttribute("src");
        }
        else{
           continue;
        }
    ····
    五、总结

    源码:

    package indi.pic_clawer;
    
    import org.openqa.selenium.By;
    import org.openqa.selenium.JavascriptExecutor;
    import org.openqa.selenium.WebDriver;
    import org.openqa.selenium.WebElement;
    import org.openqa.selenium.chrome.ChromeDriver;
    import org.openqa.selenium.chrome.ChromeOptions;
    
    import java.io.File;
    import java.io.FileOutputStream;
    import java.io.IOException;
    import java.io.InputStream;
    import java.net.URL;
    import java.util.ArrayList;
    import java.util.List;
    import java.util.Scanner;
    
    public class AutoGetBaiDuPicTest {
        //保存第一层链接
        List outUrlList ;
        //保存图片链接
        List picUrlList;
    
        public AutoGetBaiDuPicTest(){
            outUrlList = new ArrayList<>();
            picUrlList = new ArrayList<>();
        }
    
        
        public void getOutUrl(String url,String word) throws Exception{
            //设置不显示浏览器页面
            ChromeOptions chromeOptions=new ChromeOptions();
            chromeOptions.addArguments("-headless");
    
            WebDriver driver = new ChromeDriver(chromeOptions);
            driver.manage().window().maximize();
            driver.get(url);
    
            driver.findElement(By.id("kw")).sendKeys(word);
            driver.findElement(By.className("s_btn_wr")).click();
    
            Thread.sleep(400);
            for (int i = 0; i <8 ; i++) {
                ((JavascriptExecutor) driver).executescript("window.scrollTo(0.5,document.body.scrollHeight)");
                Thread.sleep(500);
            }
            Thread.sleep(1000);
    
            List webEList = driver.findElements(By.className("imgbox-border"));
    
            for (WebElement outUrl : webEList) {
                if(isElemExist(outUrl,By.cssSelector(".imgbox-border>a"))){
                    String furtherUrl = outUrl.findElement(By.tagName("a")).getAttribute("href");
                    outUrlList.add(furtherUrl);
                }else{
                    continue;
                }
            }
            driver.quit();
        }
    
        
        public void getPicUrl1(List outUrlList,String word){
    
            int i ;
            String path = "D:\program study\爬虫\BaiDuPic\"+word;
            File file = new File(path);
            if(!file.exists()){
                file.mkdirs();
            }
            InputStream in = null;
            FileOutputStream fos = null;
    
            //设置不显示浏览器页面
            ChromeOptions chromeOptions=new ChromeOptions();
            chromeOptions.addArguments("-headless");
            WebDriver driver = new ChromeDriver(chromeOptions);
    
            for (i = 0;i 
    

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/683482.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号