WebMagic爬虫框架简单使用

背景:
纯属自我爱好和学习,目前只是简单使用,在日常工作中并没有实际应用场景。

官网地址: 点我去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方法,就可以看到结果了。

上一篇:多线程-生产者消费者Exception in thread “Thread-12“ java.lang.IllegalMonitorStateException


下一篇:Deque双端队列