问题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();
}
}