分析页面并下载图片的小爬虫(基于hutool)

前言:简单的小爬虫,采集到页面后,通过正则表达式对页面中的详情url及图片url进行解析,最终把图片保存到本地。同时为了提高效率,增加了线程池和简单的文件日志记录防重复。

项目中集中使用了hutool的插件功能,也可做学习使用,可参考hutool的api文档。hutool传送门

代码如下:

package com.zn;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ExecutorService;

import cn.hutool.core.io.FileUtil;
import cn.hutool.core.thread.ThreadUtil;
import cn.hutool.core.util.ReUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.http.HttpUtil;

/**
 * 图片网站采集并下载图片示例
 * 
 * @author lds
 *
 */
public class ImgGatherDemo {
	/* 建立线程池操作,可根据任务量定义线程大小 */
	private static ExecutorService executor = ThreadUtil.newExecutor(12);

	public static void main(String[] args) {
		List<Integer> numList = new ArrayList<Integer>();
		for (int i = 2; i < 14; i++) {
			numList.add(i);
		}
		for (Integer num : numList) {
			executor.execute(() -> {
				listInfo(num);
			});
		}
		executor.shutdown();
	}

	/* 列表页地址 */
	private static String listPage = "https://www.ooxx.com/img/";
	/* 列表页正则,主要获取到详情url */
	private static String list_reg = ".*?<article.*?>.*?<header><h2><a href=\\\"(.*?)\\\".*?</article>";

	/**
	 * 采集列表页,并获得详情页url
	 * 
	 * @param curPage 页码
	 */
	public static void listInfo(int curPage) {
		System.out.println(curPage + "---------------------" + Thread.currentThread().getName());
		String pageStr = HttpUtil.get(listPage + curPage);
		List<String> infoList = ReUtil.findAllGroup1(list_reg, pageStr);
		for (String infoUrl : infoList) {
			getInfo(infoUrl, curPage);
		}
	}
	/* 详情页分页区域正则 */
	private static String info_reg1 = "<div.*?article-paging\\\">(.*?)</div>";
	/* 详情页分页区域正则,获取各分页url */
	private static String info_reg2 = "<a href=\\\"(.*?)\\\".*?</a>";

	public static void getInfo(String infoUrl, int pageNum) {
		String pageStr = HttpUtil.get(infoUrl);
		getPic(pageStr, pageNum);

		String pagNumStr = ReUtil.getGroup1(info_reg1, pageStr);
		List<String> infoChildList = ReUtil.findAllGroup1(info_reg2, pagNumStr);
		if (infoChildList == null || infoChildList.isEmpty()) {
			System.out.println("列表为空!" + pageNum + "----" + infoUrl);
			return;
		}
		/* 用txt文件记录采集日志,可防止图片重复采集,影响速度 */
		String picLogPath = "E:\\game\\zn\\picLogUrl--" + pageNum + ".txt";
		for (String infoChildUrl : infoChildList) {
			if (recordArtUrl(infoChildUrl, picLogPath)) {
				continue;
			}
			System.out.println(pageNum + "----" + infoChildUrl);
			String pageChildStr = HttpUtil.get(infoChildUrl);
			getPic(pageChildStr, pageNum);
		}
	}
	/* 详情页图片区域正则--防止页面复杂度较高或混乱 */
	private static String pic_reg1 = "<article.*?>(.*?)</article>";
	/* 获取图片地址url正则 */
	private static String pic_reg2 = "<img.*?src=\\\"(.*?)\\\".*?>";
	private static String localDir = "E:\\game\\hs-zn\\pic\\";
	/**
	 * 获取图片url,并且根据列表页分页进行文件夹分类,同时下载图片
	 * @param pageStr	详情页内容
	 * @param pageNum	列表页页码
	 */
	public static void getPic(String pageStr, int pageNum) {
		String articleStr = ReUtil.getGroup1(pic_reg1, pageStr);
		String imgUrl = ReUtil.getGroup1(pic_reg2, articleStr);
		/* 图片存放分文件夹 */
		String dowFilePath = localDir + pageNum;
		if (!FileUtil.exist(dowFilePath)) {
			FileUtil.mkdir(dowFilePath);
		}
		if (StrUtil.isEmpty(imgUrl)) {
			return;
		}
		/* 图片过滤,此处不要jpg图片 */
		if (imgUrl.contains(".jpg")) {
			return;
		}
		/* 图片下载,并且存放到指定文件夹 */
		HttpUtil.downloadFile(imgUrl, dowFilePath);

	}
	/**
	 * 记录下载图片的url,并且判断是否已下载
	 * @param infoUrl	下载图片url
	 * @param picLogPath	日志地址
	 * @return true 已下载,false 未下载
	 */
	private static boolean recordArtUrl(String infoUrl, String picLogPath) {
		if (!FileUtil.exist(picLogPath)) {
			FileUtil.writeUtf8String("", picLogPath);
		}
		List<String> artList = FileUtil.readUtf8Lines(picLogPath);
		if (artList.contains(infoUrl)) {
			return true;
		}
		artList.add(infoUrl);
		FileUtil.writeUtf8Lines(artList, picLogPath);
		return false;
	}
}

 

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

冬山兄

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值