昨天小编看到了一部不错的小说,但是没有办法下载,只能一页一页地看,于是想到了爬虫,现在Java也有了爬虫的框架,很简单,就算小白也能轻易入门,话不多说,直接上手。

1.首先引入相关依赖

不会maven的话可以按照右边直接去maven库下载添加jar包,注意不要少包,否则会报找不到类

依赖示例代码:

    <dependencies>
        <dependency>
            <groupId>us.codecraft</groupId>
            <artifactId>webmagic-core</artifactId>
            <version>0.7.5</version>
        </dependency>
    </dependencies>

2.新建类,实现 PageProcessor 接口,重写两个方法

 

 3.设置爬取文件配置属性,在 getSite 方法返回

 site对象的方法是方法链,可以连着设置很多属性,具体说几个重要的  

    //设置带爬取文件的相关配置
    private final Site site = Site.me()    // 返回Site对象,必须的

            .setCharset("utf-8")  //设置爬取网页字符集,有些网页是gbk
            .setTimeOut(1000)   //设置超时时间
            .setSleepTime(1000);    //设置休眠时间

4.添加main方法

    public static void main(String[] args) {

        // Spider.create(new FictionDownload()).thread(1).addUrl("").run();  这个基本是固定写法
        // thread(int threadNum)开启多少个线程执行   addUrl(String... urls)  爬取网页的地址,如果是小说,一般是章节目录,用来初始化,但我用的第一章地址
        Spider.create(new FictionDownload()).thread(1).addUrl("https://www.xbiquge.la/93/93746/35799191.html").run();
    }

当 Spider.create(...)...run()执行的时候,重写的 process() 方法就会执行

5.添加持久化属性和方法

    // 小说名
    private String title;

    //内容集合
    List<String> content = new ArrayList<>();


    /**
     * 自定义方法,用来持久化数据
     * @param content 文本数据
     */
    private void downBook(List<String> content) {
        //判断目录存不存在

        File file = new File("G:/Fiction");

        if (!file.exists()) {

            //如果不存在目录,则创建目录
            boolean mkdirs = file.mkdirs();

        }

        PrintWriter pw = null; //使用IO流

        try {

            //存为txt文件及其路径
            FileOutputStream fos = new FileOutputStream("G:/Fiction/" + title + ".txt");

            pw = new PrintWriter(fos, true);

            for (String string : content) {

                pw.println(string); //  "\r\n" 换行

            }

        } catch (FileNotFoundException e) {
            e.printStackTrace();

        } finally {

            if (pw != null) {
                pw.close();//关流
            }
        }

这个就不多说,两个属性一个是爬取网页保存的书名,一个是数据,方法是用来保存持久化数据的

6.分析爬取网站的属性,F12打开网页元素控制台,有些浏览器按键可能不同

记住这些需要的元素标签和 id 或 class ,我们要获取他们的内容或属性

 7.编写 process 方法,获取具体的数据

    /**
     * Spider.create(new FictionDownload()).thread(1).addUrl("").run() 的时候会自动调用一次这个方法
     * page.addTargetRequests(List<String> urls)    添加待爬虫队列     数组
     * page.addTargetRequest(String requestString)    添加待爬虫队列   单条
     *
     * @param page 当前的页面
     */
    @Override
    public void process(Page page) {

        //获取当前读取的 URL
        Selectable table = page.getUrl();

        Html html = page.getHtml();//获取当前页面

        if (table.toString().equals("https://www.xbiquge.la/93/93746/")) {

            //  如果当前链接是 首页 就会返回 true,进入这里
            // 这里我用的章节首页,小说最后一章完成会自动跳转到这里,做一些结尾的事情

            //获取书名
            title = html.xpath("[@id='info']/h1/text()").toString();

            downBook(content);
        } else {

            //获取章节名
            String chapter = html.xpath("[@class='bookname']/h1/text()").toString();

            //获取文章内容    [@id='content'] id为 content 的全部内容包括标签   /text()  获取文本
            List<String> temp = html.xpath("[@id='content']").all();

            // 对文章内容提纯处理

            String br = " <br> \n" +
                    " <br>&nbsp;&nbsp;&nbsp;&nbsp;";

            String[] split = temp.get(0).split(br);

            split[0] = split[0].substring("<div id=\"content\">\n".length() +
                    " &nbsp;&nbsp;&nbsp;&nbsp;".length());

            split[split.length - 1] = split[split.length - 1].substring(0, split[split.length - 1].length() - 6);

            content.add(chapter + "\n\n\n");
            content.addAll(Arrays.asList(split));

            // 获取下一章链接,并添加到爬虫队列
            String url = html.xpath("[@class='bottem1']/a[4]/@href").toString();
            page.addTargetRequest(url);

            System.out.println("已为当前队列添加:" + url + "链接!");
        }

    }
html.xpath()可以获取页面的属性或内容
html.xpath("[@id='content']").all()获取id为content的所有内容,包括下面的子标签html.xpath("[@class='bookname']/h1/text()")获取class为bookname的标签下h1标签下的文本html.xpath("[@class='bottem1']/a[4]/@href")获取class为bottem1的下第四个a标签下的href属性

page.addTargetRequest(url);//添加单条待爬虫队列

注:爬取网站我看了一下,最后一章再点下一页是退回小说章节目录,所有我加了一个判断,如果当前页面是章节目录,就说明最后一章结束,执行自定义方法保存数据,如果不是,则获取下一页链接,添加到爬取队列。

8.测试

 

 

9.爬取成功 ,附上所有代码

import us.codecraft.webmagic.Page;
import us.codecraft.webmagic.Site;
import us.codecraft.webmagic.Spider;
import us.codecraft.webmagic.processor.PageProcessor;
import us.codecraft.webmagic.selector.Html;
import us.codecraft.webmagic.selector.Selectable;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

/**
 * @author 童年
 * @date 2021-12-29 18:35
 */
public class FictionDownload implements PageProcessor {

    //设置带爬取文件的相关配置
    private final Site site = Site.me()

            .setCharset("utf-8")  //设置字符集
            .setTimeOut(1000)   //设置超时时间
            .setSleepTime(1000);    //设置休眠时间

    @Override
    public Site getSite() {
        return site;
    }

    // 小说名
    private String title;

    //内容集合
    List<String> content = new ArrayList<>();

    /**
     * Spider.create(new FictionDownload()).thread(1).addUrl("").run() 的时候会自动调用一次这个方法
     * page.addTargetRequests(List<String> urls)    添加待爬虫队列     数组
     * page.addTargetRequest(String requestString)    添加待爬虫队列   单条
     *
     * @param page 当前的页面
     */
    @Override
    public void process(Page page) {

        //获取当前读取的 URL
        Selectable table = page.getUrl();

        Html html = page.getHtml();//获取当前页面

        if (table.toString().equals("https://www.xbiquge.la/93/93746/")) {

            //  如果当前链接是 首页 就会返回 true,进入这里
            // 这里我用的章节首页,小说最后一章完成会自动跳转到这里,做一些结尾的事情

            //获取书名
            title = html.xpath("[@id='info']/h1/text()").toString();

            downBook(content);
        } else {

            //获取章节名
            String chapter = html.xpath("[@class='bookname']/h1/text()").toString();

            //获取文章内容    [@id='content'] id为 content 的全部内容包括标签   /text()  获取文本
            List<String> temp = html.xpath("[@id='content']").all();

            // 对文章内容提纯处理

            String br = " <br> \n" +
                    " <br>&nbsp;&nbsp;&nbsp;&nbsp;";

            String[] split = temp.get(0).split(br);

            split[0] = split[0].substring("<div id=\"content\">\n".length() +
                    " &nbsp;&nbsp;&nbsp;&nbsp;".length());

            split[split.length - 1] = split[split.length - 1].substring(0, split[split.length - 1].length() - 6);

            content.add(chapter + "\n\n\n");
            content.addAll(Arrays.asList(split));

            // 获取下一章链接,并添加到爬虫队列
            String url = html.xpath("[@class='bottem1']/a[4]/@href").toString();
            page.addTargetRequest(url);

            System.out.println("已为当前队列添加:" + url + "链接!");
        }

    }

    /**
     * 自定义方法,用来持久化数据
     * @param content 文本数据
     */
    private void downBook(List<String> content) {
        //判断目录存不存在

        File file = new File("G:/Fiction");

        if (!file.exists()) {

            //如果不存在目录,则创建目录
            boolean mkdirs = file.mkdirs();

        }

        PrintWriter pw = null; //使用IO流

        try {

            //存为txt文件及其路径
            FileOutputStream fos = new FileOutputStream("G:/Fiction/" + title + ".txt");

            pw = new PrintWriter(fos, true);

            for (String string : content) {

                pw.println(string); //  "\r\n" 换行

            }

        } catch (FileNotFoundException e) {
            e.printStackTrace();

        } finally {

            if (pw != null) {
                pw.close();//关流
            }
        }

    }

    public static void main(String[] args) {

        // Spider.create(new FictionDownload()).thread(1).addUrl("").run();  这个基本是固定写法
        // thread(int threadNum)开启多少个线程执行   addUrl(String... urls)  爬取网页的地址,如果是小说,一般是章节目录,用来初始化,但我用的第一章地址
        Spider.create(new FictionDownload()).thread(1).addUrl("https://www.xbiquge.la/93/93746/35799191.html").run();
    }
}

10.创作不易,装载请注明出处。如果此文章对您有帮助,麻烦点个赞,收藏加关注,谢谢!

更多推荐

Java版爬虫,爬网页,爬小说,完整教程,一看就会