Java版爬虫,爬网页,爬小说,完整教程,一看就会

article/2025/8/27 8:15:41

昨天小编看到了一部不错的小说,但是没有办法下载,只能一页一页地看,于是想到了爬虫,现在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 当前的页面*/@Overridepublic void process(Page page) {//获取当前读取的 URLSelectable 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>&nbsp;&nbsp;&nbsp;&nbsp;";String[] split = temp.get(0).split(br);split[0] = split[0].substring("<div id=\"content\">\n".length() +" &nbsp;&nbsp;&nbsp;&nbsp;".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);    //设置休眠时间@Overridepublic 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 当前的页面*/@Overridepublic void process(Page page) {//获取当前读取的 URLSelectable 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>&nbsp;&nbsp;&nbsp;&nbsp;";String[] split = temp.get(0).split(br);split[0] = split[0].substring("<div id=\"content\">\n".length() +" &nbsp;&nbsp;&nbsp;&nbsp;".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.创作不易,装载请注明出处。如果此文章对您有帮助,麻烦点个赞,收藏加关注,谢谢!


http://chatgpt.dhexx.cn/article/aqAp3vlr.shtml

相关文章

java-jsoup爬虫

1. 介绍 Jsoup是Java中的一个包&#xff0c;可以用于爬取页面中的数据 Jsoup爬取数据分为以下几个步骤&#xff1a; 1. 获取所爬取网页的Document对象 2. 找到所爬取数据所在的父级标签&#xff0c;将其从Document对象中解析出来&#xff0c;解析出来的内容放置在Element对象…

java爬虫 教程_Java爬虫其实也很简单,教你实用的入门级爬虫

原标题&#xff1a;Java爬虫其实也很简单&#xff0c;教你实用的入门级爬虫 任何语言都是可以爬虫的&#xff0c;只要你懂的常用的http协议啥的就可以模仿浏览器的行为获取你想要的数据。这里我将教大家一个简单实用的案例&#xff1a;如何获取全民K歌的下载链接。 ps: 这主要是…

java爬虫视频教程_JAVA开发教程:java视频教程java爬虫实战项目 百度网盘

– 源码 – 0 B |- 猫了个咪-更多IT精品课程.html – 41.00 kB |- 猫了个咪–it视频论坛.url – 51 B |- 22_项目优化三&#xff1a;邮件提醒.mp4 – 345.30 MB |- 21_项目优化二&#xff1a;爬虫项目监控[itjc8.com].mp4 – 353.40 MB |- 20-4_项目优化一&#xff1a;解决频繁…

手把手Java爬虫教学 - 1. 了解爬虫

一、什么是爬虫 先来看一下百度百科&#xff0c;了解一下爬虫~ 我们通过爬虫主要的目的就是爬取数据&#xff0c;好比 A 网站、B 网站有我们所需要的内容&#xff0c;但是这两个网站并没有给我们提供接口&#xff0c;那我们怎么能拿到上面的数据呢&#xff1f; 这时候我们就可…

java爬虫教程:模拟用户表单登录

转自&#xff1a;http://xiaolongonly.cn/2016/06/01/Reptile3/ 这个是爬虫教程第三篇&#xff0c;教大家如何模拟用户表单登录。 前期准备&#xff1a; JSOUP 1.83 jar包 Eclipse 任意版本能运行java就行 谷歌浏览器 第一步&#xff1a;依然是分析页面结构 我们要模拟C…

REmap包介绍及使用

2019独角兽企业重金招聘Python工程师标准>>> #REmap包简介 #包安装 #remapH函数 #remapH案例 #get_theme函数 #remapC函数 #markLineControl函数 #markPointControl函数 #remapC案例 REmap包简介 REmap包是R与echart的对接&#xff0c;在R里调用echar的api直接作图&…

用R语言绘制动态地图,代码奉上!(REmap包详解)

options(remap.ak="MY07CLhm3wKi4N2tQ6WP4kzz21BBZagI") 安装包 library(devtools) install_github(badbye/baidumap) install_github(lchiffon/REmap) baidumap包函数说明 getBaiduMap函数 getBaiduMap(location, width = 400, height = 400, zoom = 10, scale = …

remap()

学习自&#xff1a;【OpenCV入门教程之十七】OpenCV重映射 重映射&#xff0c;就是把一幅图像中某位置的像素放置到另一个图片指定位置的过程。为了完成映射过程, 我们需要获得一些插值为非整数像素的坐标,因为源图像与目标图像的像素坐标不是一一对应的。一般情况下&#xff…

REmap绘制地图

本文出自&#xff1a; http://blog.csdn.net/wzgl__wh/article/details/53108754 REmap这个包是通过调用百度地图API的一个程序包&#xff0c;与Google的ggmap包相比&#xff0c;不用翻墙就可以使用。其函数主要有&#xff1a;remap()&#xff0c;remapB()、remapC()、remapH()…

R语言:使用REmap绘制超炫酷的地图

REmap这个包是通过调用百度地图API的一个程序包,与Google的ggmap包相比,不用翻墙就可以使用。其函数主要有:remap(),remapB()、remapC()、remapH()四个。该程序包目前要github网站上,因此我们需要从github上面下载安装。 install.packages("devtools")#如果安装…

ioremap()

活动地址&#xff1a;CSDN21天学习挑战赛 前言 之前&#xff0c;我们使用 devmem 命令的方式&#xff0c;直接操作寄存器&#xff0c;控制 LED 的亮灭。 今天&#xff0c;我们在内核中使用 ioremap() 来实现该功能。 物理地址 vs 虚拟地址 在嵌入式 Linux 中&#xff0c;通常…

STM32和GD32的GPIO引脚的default(默认) alternate(引脚复用) remap(引脚重映射)三种用法 别把复用和重映射当一回事儿

STM32有很多内置外设&#xff0c;这些外设的外部引脚都是与GPIO复用的。也就是说&#xff0c;一个GPIO如果可以复用为内置外设的功能引脚&#xff0c;那么当这个GPIO作为内置外设使用的时候&#xff0c;就叫做复用 重映射就是引脚重映射&#xff0c;本来每个内置外设都有原来设…

OpenCV函数remap详解

OpenCV函数remap详解 remap的作用是将原影像映射到目标影像的函数。 这是OpenCV文档中的说明。 但这个描述给人的感觉是&#xff0c;云里雾里&#xff0c;到底是需要计算目标到原的映射关系&#xff0c;还是原到目标的映射呢。 经过我的实验发现是需要给出目标到原的映射关系…

remap函数

cvRemap( img1, img1r, mx1, my1 );在这个函数中mx1、my1是由前面函数计算出的校正系数&#xff0c;其指明了具体像素重新分配的位置。在learning opencv的12.3自带程序中可以发现&#xff0c;一般来说my1的值是比较集中的&#xff0c;mx1的值是比较分散的&#xff0c;这满足基…

Python-OpenCV 的 remap函数

恒等映射 result_img 和 原图一模一样 import cv2 import numpy as npimg cv2.imread("OpenCV.png") rows, cols, ch img.shape mapx np.ones(img.shape[:2], np.float32) mapy np.ones(img.shape[:2], np.float32) for i in range(rows):for j in range(cols)…

STM32重映射(Remap)

STM32重映射&#xff08;Remap&#xff09; 在外设的初始化中默认为Default重映射函数复用功能 在外设的初始化中默认为Default 在参考手册中 均有USART1的功能&#xff0c;但是若是想要用PB6与PB7作为USART1_TX与USART1_RX则需要用到重映射。 使用PA9 PA10只需要直接配置就…

Opencv remap函数

Opencv remap函数 函数签名实例应用亚像素信息扭曲特效 函数签名 void cv::remap ( InputArray src, OutputArray dst, InputArray map1, InputArray map2, int interpolation, int borderMode BORDER_CONSTANT, const Scalar & borderValue Scalar() ) 将通用几何变换…

OpenCV图像处理——重映射 remap函数

在《学习OpenCV3&#xff0c;OReilly系列丛书》中的第11章常见的图像变换中讲到的“任意映射”&#xff0c;Remap函数。函数cv::remap通常用来纠正校准的立体图像&#xff0c;包括图像变形和图像扭曲。其实这个函数在无人机拍摄延时摄影&#xff08;使用电子防抖算法&#xff0…

重映射:remap()函数

remap()函数会根据指定的映射形式&#xff0c;将原图像进行重映射几何变换&#xff0c;基于公式如下&#xff1a; dst(x, y) src( mapx(x, y), mapy(x, y) )函数原型C&#xff08;程序 / 20&#xff09;: void remap( InputArray src, OutputArray dst, InputArray map1, In…

OpenCV:remap()简单重映射

学习自&#xff1a;【OpenCV入门教程之十七】OpenCV重映射 重映射&#xff0c;就是把一幅图像中某位置的像素放置到另一个图片指定位置的过程。为了完成映射过程, 我们需要获得一些插值为非整数像素的坐标,因为源图像与目标图像的像素坐标不是一一对应的。一般情况下&#xff…