Java爬虫第四篇:使用selenium、Jsoup 抓取图片

简介: Java爬虫第四篇:使用selenium、Jsoup 抓取图片

前言

通过自动化工具selenium模拟人工浏览器行为,并捕获到html代码,并用Jsoup 处理html代码,提取出其中的图片数据。

1、安装依赖

创建Java maven工程,在pom.xml里引入依赖

<dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <!-- https://mvnrepository.com/artifact/org.jsoup/jsoup -->
        <dependency>
            <groupId>org.jsoup</groupId>
            <artifactId>jsoup</artifactId>
            <version>1.11.3</version>
        </dependency>
        <dependency>
            <groupId>org.seleniumhq.selenium</groupId>
            <artifactId>selenium-java</artifactId>
            <version>4.9.1</version>
        </dependency>

2、Selenium辅助类

包含Chrome WebDriver驱动,图片存储路径,图片下载方法等;

import lombok.extern.slf4j.Slf4j;
import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URL;
import java.net.URLConnection;
import java.util.Date;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/***
 * @title SeleniumUtil
 * @desctption Selenium辅助类
 * @author Kelvin
 * @create 2023/5/19 14:28
 **/
@Slf4j
public class SeleniumUtil {
    public final static String CHROMEDRIVERPATH = "D://java/chrome/chromedriver.exe";
    public final static String LOCATION_IMG_BASE_PATH = "D://java//code//carData/img/";
    public static void sleep(int m) {
        try {
            Thread.sleep(m);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
    /**
     * 文件下载到指定路径
     *
     * @param urlString 链接
     * @throws Exception
     */
    public static boolean download(String urlString, String parentFile , String key)  {
        String savePath = SeleniumUtil.LOCATION_IMG_BASE_PATH + parentFile + "/" + key + "/";
        String filename = new Date().getTime() + ".png";
        try{
            // 构造URL
            URL url = new URL(urlString);
            // 打开连接
            URLConnection con = url.openConnection();
            //设置请求超时为20s
            con.setConnectTimeout(20 * 1000);
            //文件路径不存在 则创建
            File sf = new File(savePath);
            if (!sf.exists()) {
                sf.mkdirs();
            }
            //jdk 1.7 新特性自动关闭
            try (InputStream in = con.getInputStream();
                 OutputStream out = new FileOutputStream(sf.getPath() + "//" + filename)) {
                //创建缓冲区
                byte[] buff = new byte[1024];
                int n;
                // 开始读取
                while ((n = in.read(buff)) >= 0) {
                    out.write(buff, 0, n);
                }
            } catch (Exception e) {
                return false;
            }
        } catch (Exception e) {
            return false;
        }
        log.info("【下载图片成功,本地地址:{}】" , savePath + filename);
        return true;
    }
    /**
     * 是否包含中文
     * @param str
     * @return
     */
    public static boolean isContainChinese(String str) {
        Pattern p = Pattern.compile("[\u4e00-\u9fa5]");
        Matcher m = p.matcher(str);
        if (m.find()) {
            return true;
        }
        return false;
    }
}

3、核心测试代码

大部分网站都是在html文档加载之后,在预定义的div里去异步请求加载数据,因此在打开网页时,需要停顿1-5秒(看网速和网站性能)。

import com.hqyj.cardata.util.SeleniumUtil;
import lombok.extern.slf4j.Slf4j;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
import org.junit.jupiter.api.Test;
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 org.springframework.boot.test.context.SpringBootTest;
import org.springframework.util.StringUtils;
import java.io.IOException;
@Slf4j
@SpringBootTest
class CarDataApplicationTests {
    @Test
    void huabanSearchSeleniumData() throws IOException {
        log.info("huabanData start!");
        String baseUrl = "https://huaban.com/search?q=";
        String parentFile = "huaban";
        System.setProperty("webdriver.chrome.driver", SeleniumUtil.CHROMEDRIVERPATH );// chromedriver localPath
        ChromeOptions chromeOptions = new ChromeOptions();
        chromeOptions.addArguments("--remote-allow-origins=*");
        chromeOptions.addArguments("–no-sandbox");  //--start-maximized
        WebDriver driver = new ChromeDriver(chromeOptions);
        String[] searchs = { "动漫" , "头像" , "情侣" , "AI" , "玫瑰花" , "PPT" , "深圳" , "广州" , "亚洲" , "别墅" , "区域"};
        String[] sortSearchName = { "dm" , "tx" , "ql" , "ai" , "mgh" , "ppt" , "sz" , "gz" , "yz" , "bs" , "qy"};
        for (int i = 0; i < searchs.length; i++) {
            getHuabanSearchData(driver , baseUrl , searchs[i] , sortSearchName[i] , parentFile );
        }
        driver.quit();
        log.info("huabanData end!");
    }
    private void getHuabanSearchData(WebDriver driver, String baseUrl , String searchName , String sortName , String parentFile) {
        String url = baseUrl + searchName;
        driver.get(url);
        WebElement mainSelectE = driver.findElement(By.cssSelector("div.kgGJbqsa"));
        //等待文档加载(大部分网页都是动态加载)
        SeleniumUtil.sleep(2000);
        JavascriptExecutor jsDriver = (JavascriptExecutor) driver;//将java中的driver强制转型为JS类型
        String js ="window.scrollTo(0, document.body.scrollHeight)";
        jsDriver.executeScript(js);
        SeleniumUtil.sleep(2000);
        //Selenium获取网页内容
        //转化为Jsoup文档处理
        Document doc = Jsoup.parse( mainSelectE.getAttribute("outerHTML") );
        Elements elements = doc.select("a.KGdb7ifV");
        log.info("a 元素的长度:{}" , elements.size() );
        if(elements!=null&&elements.size()>0) {
            for (Element ele : elements) {
                String imgPath = ele.select("img.hb-image").attr("src");
                if(StringUtils.isEmpty(imgPath) == false) {
                    log.info("图片地址:{} , 目录:{}" , imgPath , sortName);
                    SeleniumUtil.download(imgPath , parentFile , sortName );
                }
            }
        }
        SeleniumUtil.sleep(500);
    }
}

3.1、最终效果


目录
相关文章
|
3月前
|
数据采集 存储 弹性计算
高并发Java爬虫的瓶颈分析与动态线程优化方案
高并发Java爬虫的瓶颈分析与动态线程优化方案
|
4月前
|
数据采集 JSON Java
Java爬虫获取1688店铺所有商品接口数据实战指南
本文介绍如何使用Java爬虫技术高效获取1688店铺商品信息,涵盖环境搭建、API调用、签名生成及数据抓取全流程,并附完整代码示例,助力市场分析与选品决策。
|
4月前
|
数据采集 存储 JSON
地区电影市场分析:用Python爬虫抓取猫眼/灯塔专业版各地区票房
地区电影市场分析:用Python爬虫抓取猫眼/灯塔专业版各地区票房
|
4月前
|
数据采集 存储 XML
Python爬虫XPath实战:电商商品ID的精准抓取策略
Python爬虫XPath实战:电商商品ID的精准抓取策略
|
4月前
|
数据采集 存储 前端开发
动态渲染爬虫:Selenium抓取京东关键字搜索结果
动态渲染爬虫:Selenium抓取京东关键字搜索结果
|
4月前
|
数据采集 存储 前端开发
Java爬虫性能优化:多线程抓取JSP动态数据实践
Java爬虫性能优化:多线程抓取JSP动态数据实践
|
7月前
|
数据采集 存储 前端开发
Python爬虫自动化:批量抓取网页中的A链接
Python爬虫自动化:批量抓取网页中的A链接
|
7月前
|
数据采集
Haskell编程中,利用HTTP爬虫实现IP抓取
以上就是利用Haskell编写IP抓取爬虫的详细步骤。希望这篇文章的演示对于理解在Haskell这种函数式编程语言中如何实现网络爬虫有所帮助,而其中的网络访问、标签解析和列表处理等技术在许多其他的问题中都有广泛的应用。
166 26
|
7月前
|
数据采集 Web App开发 JavaScript
基于Selenium的Python爬虫抓取动态App图片
基于Selenium的Python爬虫抓取动态App图片
502 68
|
7月前
|
数据采集 缓存 监控
如何提高爬虫的抓取效率
提高爬虫的抓取效率是爬虫开发中的一个重要目标。以下是一些可以提高爬虫抓取效率的方法和技巧: 1. 合理设置请求频率 避免过高频率:频繁的请求可能会对目标服务器造成过大压力,甚至导致被封禁。合理设置请求间隔时间,例如每次请求间隔几秒到几十秒。 动态调整频率:根据目标网站的响应时间动态调整请求频率。如果响应时间较长,适当降低请求频率;如果响应时间较短,可以适当提高请求频率。
240 6