我的编程空间,编程开发者的网络收藏夹
学习永远不晚

怎么使用Java爬虫批量爬取图片

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

怎么使用Java爬虫批量爬取图片

本篇内容主要讲解“怎么使用Java爬虫批量爬取图片”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“怎么使用Java爬虫批量爬取图片”吧!

    爬取思路

    对于这种图片的获取,其实本质上就是就是文件的下载(HttpClient)。但是因为不只是获取一张图片,所以还会有一个页面解析的处理过程(Jsoup)。

    Jsoup:解析html页面,获取图片的链接。

    HttpClient:请求图片的链接,保存图片到本地。

    具体步骤

    首先进入首页分析,主要有以下几个分类(这里不是全部分类,但是这几个也足够了,这只是学习技术而已。),我们的目标就是获取每个分类下的图片。

    这里来分析一下网站的结构,我这里就简单一点吧。 下面这张图片是大致的结构,这里选取一个分类标签进行说明。 一个分类标签页含有多个标题页,然后每个标题页含有多个图片页。(对应标题页的几十张图片)

    怎么使用Java爬虫批量爬取图片

    具体代码

    导入项目依赖jar包坐标或者直接下载对应的jar包,导入项目也可。

    <dependency>    <groupId>org.apache.httpcomponents</groupId>    <artifactId>httpclient</artifactId>    <version>4.5.6</version></dependency><dependency>   <groupId>org.jsoup</groupId>   <artifactId>jsoup</artifactId>   <version>1.11.3</version></dependency>

    实体类 Picture 和 工具类 HeaderUtil

    实体类:把属性封装成一个对象,这样调用方便一点。

    package com.picture;public class Picture {private String title;private String url;public Picture(String title, String url) {this.title = title;this.url = url;}public String getTitle() {return this.title;}public String getUrl() {return this.url;}}

    工具类:不断变换 UA(我也不知道有没有用,不过我是使用自己的ip,估计用处不大了)

    package com.picture;public class HeaderUtil {public static String[] headers = {"Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.95 Safari/537.36",    "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/35.0.1916.153 Safari/537.36",    "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:30.0) Gecko/20100101 Firefox/30.0",    "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_2) AppleWebKit/537.75.14 (KHTML, like Gecko) Version/7.0.3 Safari/537.75.14",    "Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.2; Win64; x64; Trident/6.0)",    "Mozilla/5.0 (Windows; U; Windows NT 5.1; it; rv:1.8.1.11) Gecko/20071127 Firefox/2.0.0.11",    "Opera/9.25 (Windows NT 5.1; U; en)",    "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 1.1.4322; .NET CLR 2.0.50727)",    "Mozilla/5.0 (compatible; Konqueror/3.5; Linux) KHTML/3.5.5 (like Gecko) (Kubuntu)",    "Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.8.0.12) Gecko/20070731 Ubuntu/dapper-security Firefox/1.5.0.12",    "Lynx/2.8.5rel.1 libwww-FM/2.14 SSL-MM/1.4.1 GNUTLS/1.2.9",    "Mozilla/5.0 (X11; Linux i686) AppleWebKit/535.7 (KHTML, like Gecko) Ubuntu/11.04 Chromium/16.0.912.77 Chrome/16.0.912.77 Safari/535.7",    "Mozilla/5.0 (X11; Ubuntu; Linux i686; rv:10.0) Gecko/20100101 Firefox/10.0 "};}

    下载类

    多线程实在是太快了,再加上我只有一个ip,没有代理ip可以用(我也不太了解),使用多线程被封ip是很快的。

    package com.picture;import java.io.BufferedOutputStream;import java.io.File;import java.io.FileOutputStream;import java.io.IOException;import java.io.OutputStream;import java.util.Random;import org.apache.http.HttpEntity;import org.apache.http.client.ClientProtocolException;import org.apache.http.client.methods.CloseableHttpResponse;import org.apache.http.client.methods.HttpGet;import org.apache.http.impl.client.CloseableHttpClient;import org.apache.http.util.EntityUtils;import com.m3u8.HttpClientUtil;public class SinglePictureDownloader {private String referer;private CloseableHttpClient httpClient;private Picture picture;private String filePath;public SinglePictureDownloader(Picture picture, String referer, String filePath) {this.httpClient = HttpClientUtil.getHttpClient();this.picture = picture;this.referer = referer;this.filePath = filePath;}public void download() {HttpGet get = new HttpGet(picture.getUrl());Random rand = new Random();//设置请求头get.setHeader("User-Agent", HeaderUtil.headers[rand.nextInt(HeaderUtil.headers.length)]);get.setHeader("referer", referer);System.out.println(referer);HttpEntity entity = null;try (CloseableHttpResponse response = httpClient.execute(get)) {int statusCode = response.getStatusLine().getStatusCode();if (statusCode == 200) {entity = response.getEntity();if (entity != null) {File picFile = new File(filePath, picture.getTitle());try (OutputStream out = new BufferedOutputStream(new FileOutputStream(picFile))) {entity.writeTo(out);System.out.println("下载完毕:" + picFile.getAbsolutePath());}}}} catch (ClientProtocolException e) {e.printStackTrace();} catch (IOException e) {e.printStackTrace();} finally {try {//关闭实体,关于 httpClient 的关闭资源,有点不太了解。EntityUtils.consume(entity);} catch (IOException e) {e.printStackTrace();}}}}

    这是获取 HttpClient 连接的工具类,避免频繁创建连接的性能消耗。(但是因为我这里是使用单线程来爬取,所以用处就不大了。我就是可以只使用一个HttpClient连接来爬取,这是因为我刚开始是使用多线程来爬取的,但是基本获取几张图片就被禁掉了,所以改成单线程爬虫。所以这个连接池也就留下来了。)

    package com.m3u8;import org.apache.http.client.config.RequestConfig;import org.apache.http.impl.client.CloseableHttpClient;import org.apache.http.impl.client.HttpClients;import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;public class HttpClientUtil {private static final int TIME_OUT = 10 * 1000;private static PoolingHttpClientConnectionManager pcm;   //HttpClient 连接池管理类private static RequestConfig requestConfig;static {requestConfig = RequestConfig.custom().setConnectionRequestTimeout(TIME_OUT).setConnectTimeout(TIME_OUT).setSocketTimeout(TIME_OUT).build();pcm = new PoolingHttpClientConnectionManager();pcm.setMaxTotal(50);pcm.setDefaultMaxPerRoute(10);  //这里可能用不到这个东西。}public static CloseableHttpClient getHttpClient() {return HttpClients.custom().setConnectionManager(pcm).setDefaultRequestConfig(requestConfig).build();}}

    最重要的类:解析页面类 PictureSpider

    package com.picture;import java.io.File;import java.io.IOException;import java.util.List;import java.util.Map;import java.util.stream.Collectors;import org.apache.http.HttpEntity;import org.apache.http.client.ClientProtocolException;import org.apache.http.client.methods.CloseableHttpResponse;import org.apache.http.client.methods.HttpGet;import org.apache.http.impl.client.CloseableHttpClient;import org.apache.http.util.EntityUtils;import org.jsoup.Jsoup;import org.jsoup.nodes.Document;import org.jsoup.select.Elements;import com.m3u8.HttpClientUtil;public class PictureSpider {private CloseableHttpClient httpClient;private String referer;private String rootPath;private String filePath;public PictureSpider() {httpClient = HttpClientUtil.getHttpClient();}public void start(List<String> urlList) {urlList.stream().forEach(url->{this.referer = url;String dirName = url.substring(22, url.length()-1);  //根据标题名字去创建目录//创建分类目录File path = new File("D:/DragonFile/DBC/mzt/", dirName); //硬编码路径,需要用户自己指定一个if (!path.exists()) {path.mkdir();rootPath = path.toString();}for (int i = 1; i <= 10; i++) {  //分页获取图片数据,简单获取几页就行了this.page(url + "page/"+ 1);  }});}public void page(String url) {System.out.println("url:" + url);String html = this.getHtml(url);   //获取页面数据Map<String, String> picMap = this.extractTitleUrl(html);  //抽取图片的urlif (picMap == null) {return ;}//获取标题对应的图片页面数据this.getPictureHtml(picMap);}private String getHtml(String url) {String html = null;HttpGet get = new HttpGet(url);get.setHeader("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3100.0 Safari/537.36");get.setHeader("referer", url);try (CloseableHttpResponse response = httpClient.execute(get)) {int statusCode = response.getStatusLine().getStatusCode();if (statusCode == 200) {HttpEntity entity = response.getEntity();if (entity != null) {html = EntityUtils.toString(entity, "UTf-8");   //关闭实体?}}else {System.out.println(statusCode);}} catch (ClientProtocolException e) {e.printStackTrace();} catch (IOException e) {e.printStackTrace();} return html;}private Map<String, String> extractTitleUrl(String html) {if (html == null) {return null;}Document doc = Jsoup.parse(html, "UTF-8");Elements pictures = doc.select("ul#pins > li");//不知为何,无法直接获取 a[0],我不太懂这方面的知识。//那我就多处理一步,这里先放下。Elements pictureA = pictures.stream().map(pic->pic.getElementsByTag("a").first()).collect(Collectors.toCollection(Elements::new));return pictureA.stream().collect(Collectors.toMap(pic->pic.getElementsByTag("img").first().attr("alt"),pic->pic.attr("href")));}private void getPictureHtml(Map<String, String> picMap) {//进入标题页,在标题页中再次分页下载。picMap.forEach((title, url)->{//分页下载一个系列的图片,每个系列一个文件夹。File dir = new File(rootPath, title.trim());if (!dir.exists()) {dir.mkdir();filePath = dir.toString();  //这个 filePath 是每一个系列图片的文件夹}for (int i = 1; i <= 60; i++) {String html = this.getHtml(url + "/" + i);if (html == null) {//每个系列的图片一般没有那么多,//如果返回的页面数据为 null,那就退出这个系列的下载。return ; }Picture picture = this.extractPictureUrl(html);System.out.println("开始下载");//多线程实在是太快了(快并不是好事,我改成单线程爬取吧)SinglePictureDownloader downloader = new SinglePictureDownloader(picture, referer, filePath);downloader.download();try {Thread.sleep(1500);   //不要爬的太快了,这里只是学习爬虫的知识。不要扰乱别人的正常服务。System.out.println("爬取完一张图片,休息1.5秒。");} catch (InterruptedException e) {e.printStackTrace();}}});}private Picture extractPictureUrl(String html) {Document doc = Jsoup.parse(html, "UTF-8");//获取标题作为文件名String title = doc.getElementsByTag("h3").first().text();//获取图片的链接(img 标签的 class="lazy" data-src 属性)String url = doc.getElementsByAttributeValue("class", "main-image").first().getElementsByTag("img").attr("class="lazy" data-src");//获取图片的文件扩展名title = title + url.substring(url.lastIndexOf("."));return new Picture(title, url);}}

    启动类 BootStrap

    这里有一个爬虫队列,但是我最终连第一个都没有爬取完,这是因为我计算失误了,少算了两个数量级。但是,程序的功能是正确的。

    package com.picture;import java.util.ArrayList;import java.util.Arrays;import java.util.List;public class BootStrap {public static void main(String[] args) {//反爬措施:UA、refer 简单绕过就行了。//refer   https://www.mzitu.com//使用数组做一个爬虫队列String[] urls = new String[] {"https://www.mzitu.com/xinggan/",     "https://www.mzitu.com/zipai/"   };// 添加初始队列,启动爬虫List<String> urlList = new ArrayList<>(Arrays.asList(urls));PictureSpider spider = new PictureSpider();spider.start(urlList);}}

    爬取结果

    怎么使用Java爬虫批量爬取图片

    怎么使用Java爬虫批量爬取图片

    注意事项

    这里有一个计算失误,代码如下:

    for (int i = 1; i <= 10; i++) {  //分页获取图片数据,简单获取几页就行了this.page(url + "page/"+ 1);  }

    这个 i 的取值过大了,因为我计算的时候失误了。如果按照这个情况下载的话,总共会下载:4 * 10 * (30-5) * 60 = 64800 张。(每一页是含有30个标题页,大概5个是广告。) 我一开始以为只有几百张图片! 这是一个估计值,但是真实的下载量和这个不会差太多的(没有数量级的差距)。所以我下载了一会发现只下载了第一个队列里面的图片。当然了,作为一个爬虫学习的程序,它还是很合格的。

    这个程序只是用来学习的,我设置每张图片的下载间隔时间是1.5秒,而且是单线程的程序,所以速度上会显得很慢。但是那样也没有关系,只要程序的功能正确就行了,应该没有人会真的等到图片下载完吧。

    那估计要好久了:64800*1.5s = 97200s = 27h,这也只是一个粗略的估计值,没有考虑程序的其他运行时间,不过其他时间可以基本忽略了。

    到此,相信大家对“怎么使用Java爬虫批量爬取图片”有了更深的了解,不妨来实际操作一番吧!这里是编程网网站,更多相关内容可以进入相关频道进行查询,关注我们,继续学习!

    免责声明:

    ① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

    ② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

    怎么使用Java爬虫批量爬取图片

    下载Word文档到电脑,方便收藏和打印~

    下载Word文档

    猜你喜欢

    怎么使用Java爬虫批量爬取图片

    本篇内容主要讲解“怎么使用Java爬虫批量爬取图片”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“怎么使用Java爬虫批量爬取图片”吧!爬取思路对于这种图片的获取,其实本质上就是就是文件的下载(H
    2023-07-06

    如何使用Java爬虫批量爬取图片

    这篇文章主要介绍了如何使用Java爬虫批量爬取图片,对于爬虫的入门来说,图片相对来说是比较容易获取的,因为大部分图片都不是敏感数据,所以不会遇到什么反爬措施,对于入门爬虫来说是比较合适的,需要的朋友可以参考下
    2023-05-15

    python爬虫怎么批量爬取百度图片

    这篇文章将为大家详细讲解有关python爬虫怎么批量爬取百度图片,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。Python主要用来做什么Python主要应用于:1、Web开发;2、数据科学研究;3、网络爬
    2023-06-14

    使用Python爬虫爬取妹子图图片

    最近在学习Python的爬虫部分。看到有网友在分享使用爬虫爬取各种网站的图片的代码,也想自己写个玩玩。今天花时间分析了一下妹子图网站的结构和HTML代码,使用urllib2和BeautifulSoup写出了一个自动下载妹子图网站图片的脚本。
    2023-01-31

    Python爬虫:如何快速掌握Python爬虫核心技术,批量爬取网络图片

    对于爬虫,很多伙伴首选的可能就是Python了吧,我们在学习Python爬虫的时候得有侧重点,这篇文章教大家如何快速掌握Python爬虫的核心!有不清楚的地方,可以留言!1. 概述本文主要实现一个简单的爬虫,目的是从一个百度贴吧页面下载图片
    2023-06-02

    如何使用Python爬虫爬取网站图片

    这篇文章主要介绍了如何使用Python爬虫爬取网站图片,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。此次python3主要用requests,解析图片网址主要用beautif
    2023-06-22

    怎么利用Python批量爬取网页图片

    你可以使用Python的requests库来发起HTTP请求,并使用BeautifulSoup库来解析HTML文档以获取图片的URL。下面是一个简单的示例代码,用于批量爬取网页上的图片:```pythonimport requestsfro
    2023-09-27

    python爬虫怎么获取图片

    这篇文章主要讲解了“python爬虫怎么获取图片”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“python爬虫怎么获取图片”吧!首先导入库给文件加入头信息,伪装成模拟浏览器访问实现翻页翻页多
    2023-06-02

    Python爬虫实战之使用Scrapy爬取豆瓣图片

    使用Scrapy爬取豆瓣某影星的所有个人图片 以莫妮卡·贝鲁奇为例1.首先我们在命令行进入到我们要创建的目录,输入 scrapy startproject banciyuan 创建scrapy项目 创建的项目结构如下2.为了方便使用pych
    2022-06-02

    nodejs制作爬虫实现批量下载图片

    今天想获取一大批猫的图片,然后就在360流浪器搜索框中输入 猫 ,然后点击图片。就看到了一大波猫的图片: http://image.so.com/iq=%E7%8... ,我在想啊,要是审查元素,一张张手动下载,多麻烦,所以打算写程序来实现
    2022-06-04

    java多线程爬虫爬取百度图片的方法

    小编给大家分享一下java多线程爬虫爬取百度图片的方法,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!Java的特点有哪些Java的特点有哪些1.Java语言作为静
    2023-06-14

    怎么使用python爬虫爬取数据

    本篇内容介绍了“怎么使用python爬虫爬取数据”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!python爬出六部曲第一步:安装reques
    2023-06-29

    怎么使用node.js爬取知乎图片

    这篇文章主要介绍了怎么使用node.js爬取知乎图片的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇怎么使用node.js爬取知乎图片文章都会有所收获,下面我们一起来看看吧。原理初入爬虫的坑,没有太多深奥的理论知
    2023-06-17

    怎么使用python爬取网页图片

    本篇内容介绍了“怎么使用python爬取网页图片”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!在现在这个信息爆炸的时代,要想高效的获取数据,
    2023-07-02

    怎么使用matlab爬取网页图片

    要使用Matlab来爬取网页图片,可以使用以下步骤:1. 首先,需要安装和配置Matlab的Web Access Toolbox。这个工具箱可以帮助你在Matlab中进行网页数据的获取和处理。2. 使用Matlab的`webread`函数来
    2023-08-20

    怎么使用python爬虫爬取二手房数据

    这篇文章主要介绍怎么使用python爬虫爬取二手房数据,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!python的数据类型有哪些?python的数据类型:1. 数字类型,包括int(整型)、long(长整型)和flo
    2023-06-14

    使用Python爬虫怎么避免频繁爬取网站

    这期内容当中小编将会给大家带来有关使用Python爬虫怎么避免频繁爬取网站,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。python的数据类型有哪些?python的数据类型:1. 数字类型,包括int(整
    2023-06-15

    编程热搜

    • Python 学习之路 - Python
      一、安装Python34Windows在Python官网(https://www.python.org/downloads/)下载安装包并安装。Python的默认安装路径是:C:\Python34配置环境变量:【右键计算机】--》【属性】-
      Python 学习之路 - Python
    • chatgpt的中文全称是什么
      chatgpt的中文全称是生成型预训练变换模型。ChatGPT是什么ChatGPT是美国人工智能研究实验室OpenAI开发的一种全新聊天机器人模型,它能够通过学习和理解人类的语言来进行对话,还能根据聊天的上下文进行互动,并协助人类完成一系列
      chatgpt的中文全称是什么
    • C/C++中extern函数使用详解
    • C/C++可变参数的使用
      可变参数的使用方法远远不止以下几种,不过在C,C++中使用可变参数时要小心,在使用printf()等函数时传入的参数个数一定不能比前面的格式化字符串中的’%’符号个数少,否则会产生访问越界,运气不好的话还会导致程序崩溃
      C/C++可变参数的使用
    • css样式文件该放在哪里
    • php中数组下标必须是连续的吗
    • Python 3 教程
      Python 3 教程 Python 的 3.0 版本,常被称为 Python 3000,或简称 Py3k。相对于 Python 的早期版本,这是一个较大的升级。为了不带入过多的累赘,Python 3.0 在设计的时候没有考虑向下兼容。 Python
      Python 3 教程
    • Python pip包管理
      一、前言    在Python中, 安装第三方模块是通过 setuptools 这个工具完成的。 Python有两个封装了 setuptools的包管理工具: easy_install  和  pip , 目前官方推荐使用 pip。    
      Python pip包管理
    • ubuntu如何重新编译内核
    • 改善Java代码之慎用java动态编译

    目录