输入需要下载小说的网址
Document document = Jsoup
.connect("https://www.xxxxx")
.get();
分析网页中的标签,获取小说的名字,章节和对应章节链接
Element element=document.selectFirst("#maininfo #info h1");
String novelName=element.text();
//获取小说章节 标签元素同class处理
Elements elements=document.select("div.box_con");
Element element1 = elements.get(1);
//获取小说章节 链接
Elements nodes = element1.select("#list dd > a");
获取小说对应的章节后,下载小说章节内容
//获取小说 对应章节文档
Document document = Jsoup.connect(url).get();
//通过 选择器 快速选中正文内容
List<TextNode> element = document.selectXpath("//div[@id='content']/text()", TextNode.class); StringBuilder sb = new StringBuilder();
element.stream()
.map(e -> e.text().trim().replaceAll("\s+", ""))
.filter(t -> !"".equals(t))
.filter(t -> !t.contains("www.shumilou.co") && !t.contains("无弹窗阅读"))
.filter(t -> !t.contains("divstyle"))
.forEach(sb::append);
return sb.toString();
设置小说下载位置,例如电脑磁盘E:/ 磁盘位置可以自己设置
System.out.println("【"+novelName+"】下载完成");
//将 存储在内存中数据,写入 磁盘
File file = new File("E:/",novelName+".doc");
if (file.exists()) file.delete();//如果文件存在,则删除
//遍历 存储小说 章节的Map
for (int i=0;i<novelMap.size();i++){
//获取 i 对应的章节 内容
String content = novelMap.get(i);
FileUtils.writeStringToFile(file, content, StandardCharsets.UTF_8,true);
}
小说章节多,加快下载速度,开启多线程
//创建一个列表 ,用来存储多个线程对象
List<Thread> threads = new ArrayList<>();
for (int i=0;i<nodes.size();i++){
final int k=i;
//给每一个章节 开启一个线程 ,负责下载资源
Thread thread =new Thread(new Runnable() {
@Override
public void run() {
//获取每个章节
Element node=nodes.get(k);
//获取 标签体的内容
System.out.println("正在下载【"+ novelName +"】 【"+ node.text()+"】...\n");
try {
//解析正文内容
String content=parseContent(node.absUrl("href"));
//将解析后的小说每个章节,存放到Map中
novelMap.put(k,node.text()+"\n"+content+"\n");
} catch (Exception e) {
e.printStackTrace();
}
}
});
threads.add(thread);
TimeUnit.MILLISECONDS.sleep(20);
thread.start();
}
完整代码贴上,,
package june.day10;
import org.apache.commons.io.FileUtils;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.nodes.TextNode;
import org.jsoup.select.Elements;
import java.io.File;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.TimeUnit;
public class test {
public static void main(String[] args) throws IOException, InterruptedException {
//获取小说网址
Document document = Jsoup
.connect("https://www.xxxxxxx")
.get();
//获取小说名字
Element element=document.selectFirst("#maininfo #info h1");
String novelName=element.text();
//获取小说章节 标签元素同class处理
Elements elements=document.select("div.box_con");
Element element1 = elements.get(1);
//获取小说章节 链接
Elements nodes = element1.select("#list dd > a");
//创建一个 存储 键值对结构的 Map
final ConcurrentMap<Integer,String> novelMap = new ConcurrentHashMap<>();
//创建一个列表 ,用来存储多个线程对象
List<Thread> threads = new ArrayList<>();
for (int i=0;i<nodes.size();i++){
final int k=i;
//给每一个章节 开启一个线程 ,负责下载资源
Thread thread =new Thread(new Runnable() {
@Override
public void run() {
//获取每个章节
Element node=nodes.get(k);
//获取 标签体的内容
System.out.println("正在下载【"+ novelName +"】 【"+ node.text()+"】...\n");
try {
//解析正文内容
String content=parseContent(node.absUrl("href"));
//将解析后的小说每个章节,存放到Map中
novelMap.put(k,node.text()+"\n"+content+"\n");
} catch (Exception e) {
e.printStackTrace();
}
}
});
threads.add(thread);
TimeUnit.MILLISECONDS.sleep(20);
thread.start();
}
//遍历所有的线程
for (Thread thread : threads){
thread.join();//将所有的线程,加入到主线程中,为了阻塞 主线程,所有的子线程 结束后,才会继续执行主线程、
}
System.out.println("【"+novelName+"】下载完成");
//将 存储在内存中数据,写入 磁盘
File file = new File("E:/",novelName+".txt");
if (file.exists()) file.delete();//如果文件存在,则删除
//遍历 存储小说 章节的Map
for (int i=0;i<novelMap.size();i++){
//获取 i 对应的章节 内容
String content = novelMap.get(i);
FileUtils.writeStringToFile(file, content, StandardCharsets.UTF_8,true);
}
}
public static String parseContent(String url) throws IOException{
//获取小说 对应章节文档
Document document = Jsoup.connect(url).get();
//通过 选择器 快速选中正文内容
List<TextNode> element = document.selectXpath("//div[@id='content']/text()", TextNode.class);
StringBuilder sb = new StringBuilder();
element.stream()
.map(e -> e.text().trim().replaceAll("\s+", ""))
.filter(t -> !"".equals(t))
.filter(t -> !t.contains("www.shumilou.co") && !t.contains("无弹窗阅读"))
.filter(t -> !t.contains("divstyle"))
.forEach(sb::append);
return sb.toString();
}
}