昨天小编看到了一部不错的小说,但是没有办法下载,只能一页一页地看,于是想到了爬虫,现在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> ";
String[] split = temp.get(0).split(br);
split[0] = split[0].substring("<div id=\"content\">\n".length() +
" ".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> ";
String[] split = temp.get(0).split(br);
split[0] = split[0].substring("<div id=\"content\">\n".length() +
" ".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版爬虫,爬网页,爬小说,完整教程,一看就会
发布评论