首页>代码>SpringBoot爬取html生成CHM帮助文档>/springboot-chm/src/main/java/com/simon/springbootchm/spider/GetJFinalDoc.java
package com.simon.springbootchm.spider;


import com.jfinal.kit.StrKit;
import com.simon.springbootchm.util.ChmUtils;
import com.simon.springbootchm.util.CommandUtils;
import com.simon.springbootchm.util.CommandUtils;
import com.simon.springbootchm.vo.ContentsNode;
import com.simon.springbootchm.vo.DownNode;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;

import java.io.File;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * 爬取JFinal帮助文档并生成chm
 *
 * @author Simon
 */
public class GetJFinalDoc {

    private static String url = "https://www.jfinal.com/doc";
    private static String baseUrl = "https://www.jfinal.com";
    private static String projectName = "jfinal";
    private static String basePath = CommandUtils.getPath(projectName);

    public static void main(String[] args) throws IOException {
        /** 1、下载html资源 */
        ArrayList<ContentsNode> contentsDownNodes = downResource();
        String today = new SimpleDateFormat("yyyyMMdd").format(new Date());
        /** 2、创建CHM文档 */
        ChmUtils.createChm(projectName, contentsDownNodes, "index.html", "Jfinal帮助文档@" + today, true);
    }

    static class JfinalDownNode extends DownNode {
        JfinalDownNode(String url, String type, boolean cover) {
            super(url, type, cover);
        }

        JfinalDownNode(String url, String type) {
            super(url, type, false);
        }

        @Override
        protected String makeUrl() {
            if (url.startsWith("/")) {
                if (url.startsWith("//")) {
                    url = "http:" + url;
                } else {
                    url = baseUrl + url;
                }
            }
            return url;
        }

        @Override
        protected String makeNewFilePath() {
            return basePath + "/source/" + ("html".equals(type) ? "" : type + "/") + name;
        }
    }

    public static void downPage(String url) {
        try {
            JfinalDownNode page = new JfinalDownNode(url, "html", true);
            Document doc = page.getDoc();
            Elements csss = doc.select("link[href]");
            for (Element css : csss) {
                JfinalDownNode n = new JfinalDownNode(css.attr("href"), "css");
                n.saveToLocal();
                css.attr("href", "./css/" + n.getName());
            }
            doc.select("link[href]:last-child").after("<link rel=\"stylesheet\" type=\"text/css\" href=\"./css/fix.css\">");
            Elements jss = doc.select("script[src]");
            for (Element js : jss) {
                JfinalDownNode n = new JfinalDownNode(js.attr("src"), "js");
                if (n.getName().startsWith("jquery")) {
                    js.attr("src", "./js/jquery-1.12.4.min.js");
                } else if (n.getName().startsWith("bootstrap")) {
                    js.remove();
                } else {
                    js.attr("src", "./js/" + n.getName());
                    n.saveToLocal();
                }
            }
            Elements imgs = doc.select("img[src]");
            for (Element img : imgs) {
                JfinalDownNode n = new JfinalDownNode(img.attr("src"), "img");
                n.saveToLocal();
                img.attr("src", "./img/" + n.getName());
            }
            doc.select(".jf-header-box,.jf-footer-box,.doc-menu-box,meta:not([http-equiv=\"content-type\"]),style:not([href])").remove();
            doc.select(".jf-header,.jf-footer,.jf-doc-menus,meta:not([http-equiv=\"content-type\"]),style:not([href])").remove();
            Elements ps = doc.select(".jf-doc-content>p:last-child");
            if (ps.size() > 0) {
                Element p = ps.get(0);
                if ("<br>".equals(p.html())) {
                    p.remove();
                }
            }
            Elements menus = doc.select(".doc-pre-next-box a[href~=/doc/*]");
            for (Element a : menus) {
                a.attr("href", a.attr("href").replaceAll("^/doc", ".") + ".html");
            }
            Element title = doc.select(".jf-doc-title").get(0);
            doc.title(title.text());
            doc.html(doc.html().replace("$(\"#docscroll\").scrollTop($currentMenu.offset().top - 110);", ""));
            page.saveDocToLocal();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public static ArrayList<ContentsNode> downResource() {
        ArrayList<ContentsNode> nodes = new ArrayList<>();
        try {
            Document doc = Jsoup.connect(url).get();
            Elements menus = doc.select(".jf-doc-menus a");
            for (Element menu : menus) {
                String href = menu.attr("href");
                if (href.startsWith("/doc")) {
                    nodes.add(ContentsNode.newTopic(menu.text(), href.substring(5) + ".html"));
                    downPage(href);
                } else {
                    nodes.add(ContentsNode.newHeading(menu.text()));
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        return nodes;
    }

    private static void appendPage(StringBuilder sb, List<ContentsNode> nodes, boolean pageBreak) {
        for (ContentsNode node : nodes) {
            if (StrKit.notBlank(node.getPath())) {
                try {
                    Document doc = Jsoup.parse(new File(basePath + "/source/" + node.getPath()), "utf8");
                    Element content = doc.selectFirst(".jf-doc-contentbox");
                    content.select(".doc-pre-next-box").remove();
                    sb.append(content.html());
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (pageBreak) {
                sb.append("<h0>" + node.getTitle() + "</h0>");
            }
            if (node.getChildren() != null) {
                appendPage(sb, node.getChildren(), false);
            }
        }
    }
}
最近下载更多
139465  LV12 2023年3月29日
crosa_Don  LV18 2023年3月2日
最代码官方  LV167 2023年2月19日
最近浏览更多
茶茶茶百道qq 2023年9月20日
暂无贡献等级
多加两块钱  LV4 2023年6月12日
skook7  LV2 2023年6月1日
szf123  LV12 2023年5月30日
duanzhouyang  LV10 2023年5月12日
Pro_Guoli 2023年5月12日
暂无贡献等级
fewfsdaf  LV4 2023年4月18日
做你的景天  LV7 2023年4月12日
master_guo  LV7 2023年4月12日
ming_123_9715  LV23 2023年3月30日
顶部 客服 微信二维码 底部
>扫描二维码关注最代码为好友扫描二维码关注最代码为好友