你好! 欢迎你来到我的教学,这次,我将教会你如何运用JAVA爬虫,爬取小说内容,并保存在本地磁盘。
作者QQ:1919565533,欢迎提问。
通俗一点的讲,JAVA爬虫就是运用特定的技术,将网页上的数据下载到硬盘中。
要想运用JAVA爬虫,首先要在eclipse中安装相关的控件,这里我们选择Maven,Maven的好处就是可以自动下载相关的依赖,所谓的依赖就是JAVA中的导包。因为要运用JAVA爬虫,单单靠JAVA自带的JDK是不能够满足我们的需求的,这时就需要借助外来的包,一般的借用外来的包的方法有两个,一个是自己手动下载,另一个是依靠Maven,手动下载过程极其复杂且繁琐,然而依靠Maven项目,只需要安装配置好Maven,并在pom文件中输入相应的依赖并保存,这时Maven控件就会自动帮你下载并安装相应的包,非常方便。
首先登录网站:https://maven.apache.org/download.cgi
选择红框标注的文件点击下载。
A.首先在指定磁盘创建一个Maven目录,此目录用于存储刚才下载并解压出来的maven文件,接着将下载的maven解压到其中。
B.接着在Maven目录中创建一个名为repository的目录,关于这个目录的作用就是存储maven下载的jar包。
C.修改maven下conf目录中的settings.xml文件
首先配置maven下载资料的中央服务器,为什么要配置中央服务器呢,因为从maven下载的jar包都是从国外下载的,我们在国内下载的话会很慢,有时候还会崩掉,这时候我们就可以换一个源,比如阿里云。找到mirrors这一对尖括号,将如下代码粘贴进去就可以。
<mirrors>
<mirror>
<id>alimavenid>
<name>aliyun mavenname>
<url>http://maven.aliyun.com/nexus/content/groups/public/url>
<mirrorOf>centralmirrorOf>
mirror>
mirrors>
D.接着修改maven下载的数据存放的本地仓库,如果不修改默认的存放位置都是C盘,C盘满了会是什么情况大家应该都明白。
这里的路径就是一开始创建的repository目录的路径。
E.最后配置环境变量:MAVEN_HOME:指向的maven的解压目录
F.PATH:在最后添加 %MAVEN_HOME%\bin;
(以上两步学过JAVA的都明白,在此不过多阐述了)
G.最后在eclipse中配置maven
在窗口中点击首选项。
找到Maven点击Installations,由于我这里已经在eclipse中配置过maven,没有配置过的是没有maven的,然后点击Add。
选择刚刚的maven目录,点击完成。
再点击UserSettings,在Global Settings中选择刚刚配置完的settings.xml
在Local Repository中选择刚刚创建的repository目录。
至此我们的maven在eclipse中配置完成。
这里在Filter里选择maven-archetype-quickstart版本为1.4,习惯上一般选择这个。
注意Maven项目中的GroupId就相当于package,而ArtifactId则是相当于项目名。
创建完毕后,显示如上图所示,进入到pom.xml中。
在依赖中补充jsoup依赖,如上图,写完后保存。
保存过后,maven项目会自动下载相关依赖,如上图可以看到在Maven Dependencies下,可以看到我们刚才配置的jsoup的jar包,表示相关依赖已经下载完毕。
如上图找到App.java打开,此类就是我们需要书写的主方法。
这里我们将要爬取小说的网页设置为http://www.ybdu.co/0/8/。
按F12进入网页调试页面。
点击左上角的小鼠标。
将小鼠标放到要爬取的文字上点击,会出现如下图所示的界面。
单击,并观看右边网页源码区域
如上图可以看到小说的具体内容存于href中,而标题存放于text中。对于没学过html的同学可能不懂什么是href和text,这里只教你怎么爬取,如果你想更深一步的学习,推荐一本书:网络数据采集技术。
通俗一点的说:如上图,可以看到每个a都是在一个名为li的东西内,而每个li都在名为ul的一个东西内,而这个ul又在div中。
所以在进行抓取时,我们要从外往内抓取数据,我们只要抓到了一个名为panel-body的div,然后再在里面寻找一个名叫list-group list-charts的ul,然后再在ul中寻找li,将li中的a取出,并获得a的text作为爬取的文件名,保存href。这样我们就能锁定需要爬取的文章的名字和内容在网页中存储的位置。
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.Writer;
import org.jsoup.Connection;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
public class App
{
public static void main( String[] args ) throws IOException
{
//设置下载文件存放磁盘的位置
File file=new File("d:\\大宝鉴");
//判断文件夹是否存在,不存在就创建
if(!file.exists()) {
file.mkdirs();
}
//规定要爬取的网页
String url="http://www.ybdu.co/0/8/";
Connection conn=Jsoup.connect(url);
//伪装成为浏览器,有的网站爬取数据会阻止访问,伪装成浏览器可以访问,这里我伪装成Google浏览器
Document doc=conn.header("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/89.0.4389.128 Safari/537.36").get();
//寻找名叫panel-body的div,接着再在里面寻找叫list-group.list-charts的ul,再在里面寻找li,再在li里寻找a
Elements as=doc.select("div.panel-body ul.list-group.list-charts li a");
for(Element a : as) {
//对于每一个元素取出拿到href和小说名字
String href=a.attr("href");
String title=a.text();
//file:表示存放文件的位置
//href:表示要读取内容的页面
//title:表示存放文件名称
save(file,href,title);
}
}
private static void save(File file, String href, String title) throws IOException {
//在file目录下创建每一个章命名的txt文件
File f=new File(file,title+".txt");
//构建输出流对象,因为小说的内容是字符类型的数据
Writer out=new FileWriter(f);
//构建读取页面的url
//http://www.ybdu.co/0/8/6850.html
String url="http://www.ybdu.co"+href;
Connection conn=Jsoup.connect(url);
//伪装成为浏览器
Document doc=conn.header("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/89.0.4389.128 Safari/537.36").get();
//获取小说的正文
String content=doc.select("div.panel-body.content-body.content-ext").html();
//处理特殊数据
content=content.replace("一本读|WwんW.『yb→du→.co", "");
content=content.replace("
", "");
content=content.replace(" ", "");
out.write(content);
out.close();
//需要使用休眠,为了防止网站检测为蓄意攻击,停止我们的IP访问
int n=(int) (Math.random()*1000+100);
try {
Thread.sleep(n);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
Elements as=doc.select("div.panel-body ul.list-group.list-charts li a");
先上图:
div.panel-body代表的就是名叫panel-body的div块,包括里面所有的东西。以此类推, ul.list-group.list-charts代表的就是名叫,list-group list-charts的ul块,但是要注意的是这个块的名字中间有空格,这里空格用.代替,li a的意思就是拿到每一个a元素,方便以后操作。
for(Element a : as) {
//对于每一个元素取出拿到href和小说名字
String href=a.attr("href");
String title=a.text();
//file:表示存放文件的位置
//href:表示要读取内容的页面
//title:表示存放文件名称
save(file,href,title);
}
由于上述操作已经拿到了a,对于每个a我们通过attr方法,取得a的href,这里的href就是“/0/8/6850.html”,text方法就是获取a的字符串标题这里是"第一章 莫欺少年穷"。
Document doc=conn.header("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/89.0.4389.128 Safari/537.36").get();
这里的header里的参数是为了伪装成浏览器,对于某些有防爬虫的网站必须伪装成浏览器才能进行爬取,这里的参数可以当做常量来使用,你也可以伪装成IE,FireFox。这里的参数如何设置,可以看我的另一篇文章,以后会发出去。
如下图可以看到爬取的小说数量。
随便打开一个:
可以看到,小说内容已经爬取完毕了。
本文的JAVA网络爬虫主要运用的Jsoup,通过Jsoup的Connect方法构造url与Document的桥梁。通过伪装浏览器,躲过网站蓄意攻击检测,达到爬虫的目的。