软件园学生在线

  • {{ item.name }}
  • 2023试用期

登录与注册

【后端二】张云昊

  • 张云昊
  • 2022-10-23
  • 0

问题1

起初,按照培训时的代码运行,发现会报错
报错内容是url illegal了
看了看发现

try{
        chapter = Jsoup.connect(menuUrl+sublink).get();
}catch(IOException ewww){
        ewww.printStackTrace();
 }

这一步中menuUrl+sublink的结果是错的
举个例子,形如这种
https://www.aixiaxsw.com/61/61977//61/61977/43455292.html
/61/61977/重复了
返回浏览器发现这个爱下小说网每个章节的href与目录url有重复
这是与培训时所用的示例网站不同的

问题1的解决

搜关键词“截取字符串”后找到了StringUtils.substringAfterLast方法
于是乎
先在.pom文件中添加了StringUtilsde的依赖

 <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-lang3</artifactId>
            <version>3.12.0</version>
        </dependency>

然后又import org.apache.commons.lang3.StringUtils;进行导入

String sublink = a.attr("href");
String str = StringUtils.substringAfterLast(sublink,"/");
String chapterName = a.text();
System.out.println("当前爬取章节:"+chapterName);
Document chapter = null;
try{
    chapter = Jsoup.connect(menuUrl+str).get();
}catch(IOException ewww){
    ewww.printStackTrace();
 }

通过String str = StringUtils.substringAfterLast(sublink,"/");截取sublink中最后一个"/"后的字符串,解决了url重复的问题,成功运行爬虫程序

问题2

对于用户输入错误url的情况的一点处理(纯自己想的,感不是很完美)

问题2的解决

上代码!

String menuUrl = null;
do{
            String t = sc.next();
            if(Objects.equals(t, "1")){
                menuUrl = "https://www.aixiaxsw.com/15/15675/";
                System.out.println("您输入了1,即将爬取示例小说《诛仙》");
                break;
            }else{
                if(t.contains("https://www.aixiaxsw.com/")||t.contains("http://www.aixiaxsw.com/")){
                    menuUrl = t;
                    System.out.println("请耐心等待,即将开始爬取");
                    break;
                }else{
                    System.out.println("您输入的url格式有误或输入的数字不为1,请重新输入");
                }

            }

}while (sc.hasNext());

只要用户输入的url并非爱下小说网的或者输入的数字不是1或者输入的并非url(输入了一串字母啥的),便会进入循环重新输入,也考虑了http和https两种情况
不足:无法解决类如输入https://www.aixiaxsw.com/102/12765 这种只少了最后一个"/"的情况。

问题3

给用户的提示信息:弄了不少,不放了吧,都在最下面的代码里嘿嘿

问题4及处理

对于目录、作者的爬取以及超链接的加入

System.out.println("正在爬取目录,请耐心等待");
        for(Element a : as){
            String sublink = a.attr("href");
            String str = StringUtils.substringAfterLast(sublink,"/");
            String chapterName = a.text();
            fileOut.write(("**"+chapterName+"**"+"[官网]("+menuUrl+str+")"+"\n\n").getBytes());
        }

这个还是比较简单的,模仿着培训里讲的for循环(爬取每一章节的标题和内容)就能写出来。
爬作者就和爬书名一样String author = document.body().selectFirst("p").text();
之后在输出流中加上author就行了

问题5

markdown排版,浅浅加了加标题,给作者加粗啥的
不足:没搞懂咋复原不同段落

问题6

在ppt里给的网站中学会了只打胖包(发到邮箱里了)

代码

import org.apache.commons.lang3.StringUtils;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;

import java.io.*;
import java.util.Objects;
import java.util.Scanner;

        public class Spider{
            public static void main(String[] args) throws IOException{
                final String fileAddr = "./";
                Scanner sc = new Scanner(System.in);
                System.out.println("请输入所要爬取小说的目录页的Url," +
                        "形如https://www.aixiaxsw.com/26/26449/");
                System.out.println("一定要注意url的格式!!!");
                System.out.println("也可输入“1”爬取示例小说《诛仙》");

                String menuUrl = null;
                do{
                    String t = sc.next();
                    if(Objects.equals(t, "1")){
                        menuUrl = "https://www.aixiaxsw.com/15/15675/";
                        System.out.println("您输入了1,即将爬取示例小说《诛仙》");
                        break;
                    }else{
                        if(t.contains("https://www.aixiaxsw.com/")||t.contains("http://www.aixiaxsw.com/")){
                            menuUrl = t;
                            System.out.println("请耐心等待,即将开始爬取");
                            break;
                        }else{
                            System.out.println("您输入的url格式有误或输入的数字不为1,请重新输入");
                        }

                    }

                }while (sc.hasNext());

                Document document = null;
                try{
                    document = Jsoup.connect(menuUrl).get();
                }catch(IOException ewww){
                    ewww.printStackTrace();
                }
                String title = document.body().selectFirst("h1").text();
                String author = document.body().selectFirst("p").text();

                System.out.println("开始爬取:"+title);
                Elements menu = document.body().select("dl dd");
                Elements as = menu.select("a[href]");

                System.out.println("小说将保存在:"+fileAddr+title+".md中");

                File file =new File(fileAddr+title+".md");
                OutputStream fileOut = null;
                try{
                    fileOut = new FileOutputStream(file);
                }catch(FileNotFoundException e){
                    e.printStackTrace();
                }

                fileOut.write(("#"+" " +title+"\n\n"+"**"+author+"**"+"\n\n"+"### 目录 ###"+"\n\n").getBytes());

                System.out.println("正在爬取目录,请耐心等待");
                for(Element a : as){
                    String sublink = a.attr("href");
                    String str = StringUtils.substringAfterLast(sublink,"/");
                    String chapterName = a.text();
                    fileOut.write(("**"+chapterName+"**"+"[官网]("+menuUrl+str+")"+"\n\n").getBytes());
                }

                for(Element a : as){

                    String sublink = a.attr("href");
                    String str = StringUtils.substringAfterLast(sublink,"/");
                    String chapterName = a.text();
                    System.out.println("当前爬取章节:"+chapterName);
                    Document chapter = null;
                    try{
                        chapter = Jsoup.connect(menuUrl+str).get();
                    }catch(IOException ewww){
                        ewww.printStackTrace();
                    }
                    Element chapterContent = chapter.selectFirst("#content");

                    fileOut.write(("\n\n"+"#### "+chapterName+"\n\n"+chapterContent.text()).getBytes());

                }
                System.out.println("小说爬取完成 ");
                System.out.println("注意:正文中前几章为最新章节," +
                        "而后才是从第一张开始的有序章节");

                fileOut.close();
            }
        }
张云昊
张云昊
© 2025 软件园学生在线
Theme by Wing