网站中的图片和网页在本质上是相同的,图片和网页的获取本质上都是根据URL从网站中获取网页/图片的字节数组(byte[]),浏览器会根据http响应头中的content-type信息来决定以网页还是图片的形式来展示资源。
完整的图片抓取示例工程可加群250108697在群文件中获取。
示例中的代码爬取了美食杰中的图片到指定的文件夹中,爬取结果如下图所示:
核心代码:
import cn.edu.hfut.dmic.webcollector.model.CrawlDatums;
import cn.edu.hfut.dmic.webcollector.model.Page;
import cn.edu.hfut.dmic.webcollector.plugin.berkeley.BreadthCrawler;
import cn.edu.hfut.dmic.webcollector.plugin.net.OkHttpRequester;
import cn.edu.hfut.dmic.webcollector.util.ExceptionUtils;
import cn.edu.hfut.dmic.webcollector.util.FileUtils;
import cn.edu.hfut.dmic.webcollector.util.MD5Utils;
import java.io.File;
/**
* WebCollector抓取图片的例子
* @author hu
*/
public class DemoImageCrawler extends BreadthCrawler {
File baseDir = new File("images");
/**
* 构造一个基于伯克利DB的爬虫
* 伯克利DB文件夹为crawlPath,crawlPath中维护了历史URL等信息
* 不同任务不要使用相同的crawlPath
* 两个使用相同crawlPath的爬虫并行爬取会产生错误
*
* @param crawlPath 伯克利DB使用的文件夹
*/
public DemoImageCrawler(String crawlPath) {
super(crawlPath, true);
//只有在autoParse和autoDetectImg都为true的情况下
//爬虫才会自动解析图片链接
getConf().setAutoDetectImg(true);
//如果使用默认的Requester,需要像下面这样设置一下网页大小上限
//否则可能会获得一个不完整的页面
//下面这行将页面大小上限设置为10M
//getConf().setMaxReceiveSize(1024 * 1024 * 10);
//添加种子URL
addSeed("http://www.meishij.net/");
//限定爬取范围
addRegex("http://www.meishij.net/.*");
addRegex("http://images.meishij.net/.*");
addRegex("-.*#.*");
addRegex("-.*\\?.*");
//设置为断点爬取,否则每次开启爬虫都会重新爬取
// demoImageCrawler.setResumable(true);
setThreads(30);
}
@Override
public void visit(Page page, CrawlDatums next) {
//根据http头中的Content-Type信息来判断当前资源是网页还是图片
String contentType = page.contentType();
//根据Content-Type判断是否为图片
if(contentType!=null && contentType.startsWith("image")){
//从Content-Type中获取图片扩展名
String extensionName=contentType.split("/")[1];
try {
byte[] image = page.content();
//根据图片MD5生成文件名
String fileName = String.format("%s.%s",MD5Utils.md5(image), extensionName);
File imageFile = new File(baseDir, fileName);
FileUtils.write(imageFile, image);
System.out.println("保存图片 "+page.url()+" 到 "+ imageFile.getAbsolutePath());
} catch (Exception e) {
ExceptionUtils.fail(e);
}
}
}
public static void main(String[] args) throws Exception {
DemoImageCrawler demoImageCrawler = new DemoImageCrawler("crawl");
demoImageCrawler.setRequester(new OkHttpRequester());
//设置为断点爬取,否则每次开启爬虫都会重新爬取
demoImageCrawler.setResumable(true);
demoImageCrawler.start(3);
}
}