背景:
纯属自我爱好和学习,目前只是简单使用,在日常工作中并没有实际应用场景。
官网地址: 点我去WebMagic官网
官方文档地址:点我去官方文档
直接上代码:
import us.codecraft.webmagic.Page;
import us.codecraft.webmagic.Request;
import us.codecraft.webmagic.Site;
import us.codecraft.webmagic.Spider;
import us.codecraft.webmagic.processor.PageProcessor;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.List;
/**
* @author javaboy
* @version 1.0
* @data 2021/1/19 9:37 PM
* @description 爬虫demo
* @url
*/
public class GetPhoto implements PageProcessor {
/**
* 设置参数
*/
private Site site = Site.me().setRetryTimes(3).setSleepTime(1000).setTimeOut(3000);
/**
* 主方法启动爬虫
*/
public static void main(String[] args) {
// 这里只爬取第一页的壁纸,如果要爬取其他页数修改for循环参数即可
for (int i = 10; i <= 11; i++) {
// 启动爬虫
Spider.create(new GetPhoto())
// 添加初始化的URL
.addUrl("https://wallhaven.cc/toplist?page=" + i)
// 使用单线程
.thread(1)
// 运行
.run();
}
}
/**
* 页面处理逻辑
* 也就是访问主程序中的URL后得到的页面
* <p>
* 爬虫思路:
* 1. 主程序访问URL后得到页面
* 2. 将得到的页面解析出需要的参数,并将解析出来并且需要爬取的链接放入爬取目标中 (45-59行)
* TIPS:WebMagic会自动去识别哪些连接爬取过哪些没有。
* 3. 访问第二步中放入的链接得到页面,并解析(62行)
* 4. 将图片的名字和后缀提取出来以便保存(64-77行)
*/
@Override
public void process(Page page) {
// 一页是24张图片
for (int i = 1; i <= 24; i++) {
// 使用Xpath解析,获取到单个图片的网页
// WebMagic支持使用Xpath、CSS选择器、正则表达式、JsonPath来解析页面
String str = page.getHtml().xpath("//div[@id=thumbs]/section/ul/li[" + i + "]/figure//img/@data-src").toString();
// 获取到的连接为null则退出循环,不添加进爬取目标
if (str == null) {
break;
}
// 将爬取到的链接添加到待爬取页面中
page.addTargetRequest(str);
}
// 将页面中图片的地址提取出来,以便于使用工具类保存
List<Request> targetRequests = page.getTargetRequests();
for (int i = 0; i < targetRequests.size(); i++) {
String pageURL = targetRequests.get(i).getUrl();
if (pageURL != null) {
try {
// 获取图片的名字和后缀提取出来用于保存
String name = pageURL.substring(pageURL.length() - 10, pageURL.length() - 4);
String suffix = pageURL.substring(pageURL.length() - 4);
// 将图片的地址、名字、保存路径传入文件工具类进行下载
DownloadImage.downLoadFromUrl(pageURL, name + suffix, "src/file/");
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
@Override
public Site getSite() {
return site;
}
}
import java.io.*;
import java.net.HttpURLConnection;
import java.net.URL;
/**
* @author javaboy
* @version 1.0
* @data 2021/1/19 9:39 PM
* @description 下载器
* @url
*/
public class DownloadImage {
public static void downLoadFromUrl(String urlStr, String fileName, String savePath) throws IOException {
URL url = new URL(urlStr);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
// 设置超时间为3秒
conn.setConnectTimeout(3 * 1000);
// 防止屏蔽程序抓取而返回403错误
conn.setRequestProperty("User-Agent", "Mozilla/4.0 (compatible; MSIE 5.0; Windows NT; DigExt)");
// 得到输入流
InputStream inputStream = conn.getInputStream();
// 获取自己数组
byte[] getData = readInputStream(inputStream);
// 文件保存位置
File saveDir = new File(savePath);
if (!saveDir.exists()) {
saveDir.mkdir();
}
File file = new File(saveDir + File.separator + fileName);
FileOutputStream fos = new FileOutputStream(file);
fos.write(getData);
if (fos != null) {
fos.close();
}
if (inputStream != null) {
inputStream.close();
}
System.out.println("info:" + url + " download success");
}
private static byte[] readInputStream(InputStream inputStream) throws IOException {
byte[] buffer = new byte[1024];
int len = 0;
ByteArrayOutputStream bos = new ByteArrayOutputStream();
while ((len = inputStream.read(buffer)) != -1) {
bos.write(buffer, 0, len);
}
bos.close();
return bos.toByteArray();
}
}
直接运行main方法,就可以看到结果了。