JAVA爬虫项目学习笔记(Maven框架)

项目介绍

项目要求:

使用JAVA制作爬虫,操作API爬取网页的信息,保存到本地。

实现原理

使用Jsoup解析HTML,获取网站源代码,通过解析HTML获取需要的数据,并保存本地。

Maven框架

Maven配置

配置Maven环境

首先要去下载Maven,这里是在Maven的下载地址: Maven – Download Apache Maven,然后解压到你想要的地方,然后打开bin文件夹,复制路径

然后配置环境变量(MAVEN_HOME 和 Path都设置成你安装目录下的bin目录 )。

然后Windows + R 输入 CMD,接着输入 mvn -v 来看看是否配置成功环境变量。

如果输出版本,就说明配置成功。

配置Maven设置

紧接着要开始设置Maven了

首先打开conf文件夹,打开settings.xml

找到 <localRepository>/path/to/local/repo</localRepository>这句,复制出来,中间的 /path/to/local/repo 这句是定义自己想要的Jar包的位置,选择自己想要的位置

然后配置Jar包下载的镜像。找到里面的 <mirror> 标签,然后改为阿里云的镜像

<!--阿里云镜像-->
<mirror>
      <id>nexus-aliyun</id>
      <mirrorOf>central</mirrorOf>
      <name>Nexus aliyun</name>
      <url>http://maven.aliyun.com/nexus/content/groups/public</url>
</mirror>

然后保存,Maven设置完成。

IDJA上的Maven设置

打开IDJA ,点击“文件”,进入”新项目设置”。(英文版为: 点击File ,进入Other Settings Of New Project \New Project Settings)

搜索Maven(英文版同理)。

在”用户设置文件“导入之前在Setting.xml的设置,在“本地仓库”选择之前在Setting.xml中设置的Jar的路径,“Maven主路径”选择conf的上一级文件夹。(英文对照: “Maven主路径” : Maven home directopry ,”用户设置文件” : User settings file,”本地仓库” : Local repository)

导入Setting.xml后”本地仓库(Local repository)”和’用户设置文件(User settings file)”后面的”重写”(Override)记得勾选

然后点击”应用”(Apply)。

IDJA 的 Maven 设置成功o(〃^▽^〃)o

Maven目录结构

Maven1//Maven项目名
    └─src
        ├─main
        │  ├─java
        │  └─resources
        └─test
            ├─java
            └─resources
  • Windows系统显示文件目录树

在CMD窗口下输入

Tree + [查看目录树的地址]

就可显示了

Maven仓库依赖

点击此链接进入Maven仓库,点击选择需要的API版本,点击在需要的API找到Maven点击即可复制。

CMD编译和运行Maven项目

cmd找到项目的根目录,找到maven项目的根目录,在地址框输入cmd,回车(或者win + R,输入cmd打开cmd窗口然后 cd maven项目路径 ),在弹出的cmd窗口中输入 mvn compile 编译。输出 “BUILD SUCCESS”说明编译成功。

我们看到了出现了这样的提示:

是因为编码设置的不正确,这时候要打开项目的pom.xml文件,在<properties> 里加入下面这句

<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>

然后再运行mvn compile 就不报错啦。

运行Maven项目

写一个JAVA程序

public class Main {
    public static void main(String[] args){
        System.out.println("Hello,Maven!");
    }
}

然后在当前Cmd窗口下输入 mvn exec:java -Dexec.mainClass="PC" 就可以运行在main问减价下的Main类中的Main方法。

mvn exec:java -Dexec.mainClass="PC"  
//注意: PC是我自己写的JAVA类名,-Dexec.mainClass会让Maven从项目目录的main文件夹开始
mvn exec:java -Dexec.mainClass="" 

编译完成输出结果:

JAVA爬虫

配置到Maven框架,就可以愉快的编写JAVA爬虫了。

爬虫 : 按照一定的规则,自动地抓取万维网信息的程序或者脚本

环境配置

前提:

IntelliJ IDEA

Maven框架

JDK 1.8

安装需要的Jar包

以下的所有Jar包均可在Maven仓库 https://mvnrepository.com/ 下载

接着要安装Jsoup包,用于解析HTML并查找(均放在<dependencies></dependencies>标签中 )

<!-- https://mvnrepository.com/artifact/org.jsoup/jsoup -->
<dependency>
    <groupId>org.jsoup</groupId>
    <artifactId>jsoup</artifactId>
    <version>1.14.3</version>
</dependency>

还有SLF4J包,用来记录日志。

<!-- https://mvnrepository.com/artifact/org.slf4j/slf4j-log4j12 -->
<dependency>
    <groupId>org.slf4j</groupId>
    <artifactId>slf4j-log4j12</artifactId>
    <version>1.7.25</version>
    <scope>test</scope>
</dependency>

Commons-io,常用的工具类

<!-- https://mvnrepository.com/artifact/commons-io/commons-io -->
<dependency>
    <groupId>commons-io</groupId>
    <artifactId>commons-io</artifactId>
    <version>2.11.0</version>
</dependency>

以及处理字符串的common-lang3

<!-- https://mvnrepository.com/artifact/org.apache.commons/commons-lang3 -->
<dependency>
    <groupId>org.apache.commons</groupId>
    <artifactId>commons-lang3</artifactId>
    <version>3.12.0</version>
</dependency>

配置SLF4J

在resources下创建一个SLF4J配置文件,名为 log4j.properties

写入配置代码:

log4j.rootLogger=DEBUG,A1
log4j.logger.cn.itcast = DEBUG
log4j.appender.A1=org.apache.log4j.ConsoleAppender
log4j.appender.A1.layout=org.apache.log4j.PatternLayout
log4j.appender.A1.layout.ConversionPattern=%-d{yyyy-MM-dd HH:mm:ss, SSS} [%t] [%c]-[%p] %m%n

至此Java的环境配置完成。

JAVA爬虫编写

使用 Jsoup 实现爬取文章封面

分析源代码,找出封面位置,是在<div class="cover">中的<img>标签的data-src属性

接下来的操作,将围绕这个<div>框和里面的<img>标签展开

import org.jsoup.Connection;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
import org.apache.commons.io.*;
import java.io.*;
import java.net.URL;
import java.net.URLConnection;

public class Main {
    public static void main(String[] args) throws IOException{
        /*获取HTML*/
        //String Url = "https://xenolies.xyz/";  //爬取网站2
        String Url = "https://xenolies.github.io/";//需要爬取的网站URL
        //使用Jsoup.connect()方法链接Url,获取HTML文件
Connection connection =  Jsoup.connect(Url);
        //设置延时,避免出现Connection reset错误
        connection.timeout(3000); 
        //使用Get(),解析HTML,使用Document来接受返回的信息
        Document document = connection.get();  

        /*使用各种选择器来解析获取获取到的HTML*/ 
        //使用Class选择元素,获取所有名为cover的元素
        Elements cover = document.getElementsByClass("cover"); 
        //创建list来保存爬出的图片URL
        String[] UrlList = new String[cover.size()];  
        //for循环持续爬取图片,.size()获取循环次数
        for (int Time = 0;Time < cover.size();Time++){ 
            /*从获取的元素中获取数据*/
            //获取属性值
            //获取cover中的包含<img>标签的第几个<div>(数组排列)
            Element div = cover.get(Time);
            Elements imgUrl = div.getElementsByTag("img");  //获取到<img标签>
            String ImgUrl = imgUrl.attr("data-src");
            System.out.println("第" + (Time+1) + "张图片");
            UrlList[Time] = ImgUrl;  //将单个的图片地址添加进数组
        }
        String filePath = "C:\\Users\\35367\\Desktop\\Webps" ;  //图片保存的位置

        for (int i = 0;i < cover.size();i++){  //遍历,下载
            File dir = new File(filePath);
            //substring()方法来截取字符串,lastIndexOf()来截取最后一个 "/"出现时候的位置(要+1来跳过)
            String fileName = UrlList[i].substring(UrlList[i].lastIndexOf("/") + 1,UrlList[i].length());
            //File.separator为分隔符,在什么系统使用法对应的分隔符,用于保存
            File file = new File(filePath + File.separator + fileName);  //输出的路径

            Connection connectionIMG = Jsoup.connect(UrlList[i]);  //建立新的connection
            URL url =new URL(UrlList[i]);  //new成为Url以便后面使用
            URLConnection ConnectionIMG = url.openConnection();  
            InputStream in = ConnectionIMG.getInputStream();
            OutputStream out = new BufferedOutputStream(new FileOutputStream(file));

            byte[] buf = new byte[1024];
            int len = -1;

            while ((len = in.read(buf)) != -1) {
                out.write(buf, 0, len);
            }

        }
    }

}

爬取结果:

这样不是很方便整理,所以需要生成个表格。

那就用HSSFWorkBook生成个表格。

import org.apache.poi.hssf.usermodel.HSSFCell;
import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.jsoup.Connection;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
import java.io.*;
import java.net.URL;
import java.net.URLConnection;

public class ImageExcel {
    public static void main(String[] args) throws IOException{
        /*获取HTML*/
        //String Url = "https://xenolies.xyz/";  //爬取网站2
        String Url = "https://xenolies.github.io/page/2";//需要爬取的网站URL
        Connection connection =  Jsoup.connect(Url);//使用Jsoup.connect()方法链接Url,获取HTML文件

        //connection.timeout(3000);  //设置延时,避免出现Connection reset错误


        Document document = connection.get();  //使用Get(),解析HTML,使用Document来接受返回的信息

        /*使用各种选择器来解析获取获取到的HTML*/
        Elements cover = document.getElementsByClass("cover"); //使用Class选择元素,获取所有名为cover的元素

        String[] UrlList = new String[cover.size()];  //创建list来保存爬出的图片URL

        for (int Time = 0;Time < cover.size();Time++){  //for循环持续爬取图片,.size()获取循环次数

            /*从获取的元素中获取数据*/
            //获取属性值
            Element div = cover.get(Time);  //获取cover中的包含<img>标签的第几个<div>(数组排列)
            Elements imgUrl = div.getElementsByTag("img");  //获取到<img标签>

            String ImgUrl = imgUrl.attr("data-src");
            System.out.println("第" + (Time+1) + "张图片");
            System.out.println(ImgUrl);//查看输出的图片Url
            UrlList[Time] = ImgUrl;  //将单个的图片地址添加进数组
        }
        HSSFWorkbook hssfWorkbook = new HSSFWorkbook();
        HSSFSheet hssfSheet = hssfWorkbook.createSheet("Images");
        hssfSheet.setColumnWidth(0, 10000);
        hssfSheet.setColumnWidth(1, 20000);

        String filePath = "C:\\Users\\35367\\Desktop\\Webps" ;  //图片保存的位置
        String ExcelPath = "C:\\Users\\35367\\Desktop\\ImageExcel.xls"; //Excal位置

        for (int i = 0;i < cover.size();i++){

            //遍历,下载
            File dir = new File(filePath);
            //substring()方法来截取字符串,lastIndexOf()来截取最后一个 "/"出现时候的位置(要+1来跳过)
            String fileName = UrlList[i].substring(UrlList[i].lastIndexOf("/") + 1,UrlList[i].length());
            if (i ==0){
                HSSFRow Row = hssfSheet.createRow(i);  //行
                HSSFCell cell1 = Row.createCell(0);
                HSSFCell cell2 = Row.createCell(1);
                cell1.setCellValue("FileName");
                cell2.setCellValue("ImageURL");
            }else {
                HSSFRow Row = hssfSheet.createRow(i);  //行
                HSSFCell cell1 = Row.createCell(0);
                HSSFCell cell2 = Row.createCell(1);
                cell1.setCellValue(fileName);
                cell2.setCellValue(UrlList[i]);
            }


            //File.separator为分隔符,在什么系统使用法对应的分隔符,用于保存
            File file = new File(filePath + File.separator + fileName);  //输出的路径

            URL url =new URL(UrlList[i]);  //new成为Url以便后面使用
            URLConnection ConnectionIMG = url.openConnection();
            InputStream in = ConnectionIMG.getInputStream();
            OutputStream out = new BufferedOutputStream(new FileOutputStream(file));

            byte[] buf = new byte[1024];
            int len = -1;

            while ((len = in.read(buf)) != -1) {
                out.write(buf, 0, len);
            }

            FileOutputStream fos = new FileOutputStream(ExcelPath);  //IO流写入
            hssfWorkbook.write(fos);
            fos.close();
            System.out.println("Imgage.xls创建成功");
            System.out.println(fileName + " 已下载");
        }


    }

}

运行结果:

Jsoup + HSSFWorkbook 爬取,生成表格

这次爬取的网页时LR2 的段位表

F12打开控制台,查看源代码,

发现我们要找的东西在 <tr> 框的 <th>标签和 <td>标签里面,单纯的提取 <tr>会导致混乱,所以要加入一个判断。

因为段位表是表格,所以我们要引入一个新的Jar包 Poi ,来制作导出表格

<!-- https://mvnrepository.com/artifact/org.apache.poi/poi -->
<dependency>
    <groupId>org.apache.poi</groupId>
    <artifactId>poi</artifactId>
    <version>4.1.2</version>
</dependency>

使用教程可以参考这个 :使用HSSFWorkbook导出、操作excell

代码如下 :

import org.apache.poi.hssf.usermodel.*;
import org.jsoup.Connection;
import org.jsoup.Jsoup ;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
import java.io.FileOutputStream;
import java.io.IOException;

public class Main {

    public static void main(String[] args) throws IOException {
        //确认爬取的HTML网页,
        String url = "http://www.dream-pro.info/~lavalse/LR2IR/search.cgi?mode=gradelist";
        //链接网页
        Connection connection = Jsoup.connect(url);

        //获取网站源代码
        Document document = connection.get();

        SPRank(document);
        DPRank(document);

    }


    public static void SPRank(Document document) throws IOException {

        Elements Table = document.getElementsByTag("table");
        Element table = Table.get(0);

        Elements Tr = table.getElementsByTag("tr");
        //System.out.println(Tr);
        Elements H3 = document.getElementsByTag("h3");
        //System.out.println(H3);
        String h31 = H3.get(0).text();  //SP段位名

        HSSFWorkbook hssfWorkbook = new HSSFWorkbook();  //创建Excal表
        HSSFSheet hssfSheetSP = hssfWorkbook.createSheet(h31);  //创建名为 :"段位認定 シングル(2018) " Excel
        //设置单元格宽度
        hssfSheetSP .setColumnWidth(1, 8000);
        HSSFCellStyle cellStyle= hssfWorkbook.createCellStyle();
        //设置水平对齐的样式为居中对齐;
        cellStyle.setAlignment(HSSFCellStyle.ALIGN_CENTER);

        //设置字体
        HSSFFont font = hssfWorkbook.createFont();
        font.setFontName("黑体");



        int Th1 = 0;  //列数
        int Tr1 = Tr.size();  //行数

        String star = "";  //小段位星级
        String gradename = "";  //小段位名
        String crossnum = "";  //小合格人数
        String challengesnum = "";  //小挑战人数
        String yield = "";  //小合格率

        String Star = "";  //段位星级
        String GradeName = "";  //段位名
        String CrossNum = "";  //合格人数
        String ChallengesNum = "";  //挑战人数
        String Yield = "";  //合格率

        for (int Tri = 0; Tri < Tr.size(); Tri++) {
            Element TrTitle = Tr.get(Tri);  //第几个Tr框
            Elements Td = TrTitle.getElementsByTag("td");  //合格率等标题 : <th> 其他的时 : <td>
            Elements Th = TrTitle.getElementsByTag("th");
            HSSFRow hssfRow = hssfSheetSP.createRow(Tri);  //在对应的行中填入数据,定位行
            HSSFCell cell1 = hssfRow.createCell(0);  //第rowi行第一个单元格
            HSSFCell cell2 = hssfRow.createCell(1);
            HSSFCell cell3 = hssfRow.createCell(2);
            HSSFCell cell4 = hssfRow.createCell(3);
            HSSFCell cell5 = hssfRow.createCell(4);

            if (Td.size() == 0) {  //获取小段位内容
            } else {
                star = Td.get(0).text();
                gradename = Td.get(1).text();
                crossnum = Td.get(2).text();
                challengesnum = Td.get(3).text();
                yield = Td.get(4).text();
                cell1.setCellValue(star);
                cell2.setCellValue(gradename);
                cell3.setCellValue(crossnum);
                cell4.setCellValue(challengesnum);
                cell5.setCellValue(yield);
            }

            if (Th.size() == 0) {  //获取段位表内容
            } else {
                Th1 = Th.size();  //获取列数
                Star = Th.get(0).text();
                GradeName = Th.get(1).text();
                CrossNum = Th.get(2).text();
                ChallengesNum = Th.get(3).text();
                Yield = Th.get(4).text();
                cell1.setCellValue(Star);
                cell2.setCellValue(GradeName);
                cell3.setCellValue(CrossNum);
                cell4.setCellValue(ChallengesNum);
                cell5.setCellValue(Yield);
            }


            //表名  : 段位認定 シングル(2018) (h31)
            //项目名 : 1.星级 Star 2.段位名 GradeName 3.合格人数 CrossNum 4.挑战人数 ChallengesNum 5.通过率 Yield
            //行数: Tr1 , 列数 : Th1

        }

        FileOutputStream fos = new FileOutputStream("C:\\Users\\35367\\Desktop\\LR2(SP).xls");  //IO流写入
        hssfWorkbook.write(fos);
        fos.close();
        System.out.println("SPRank创建成功");

}









    public static void DPRank(Document document) throws IOException{

        Elements Table = document.getElementsByTag("table");
        Element table = Table.get(1);

        Elements Tr = table.getElementsByTag("tr");
        //System.out.println(Tr);
        Elements H3 = document.getElementsByTag("h3");
        //System.out.println(H3);
        String h32 = H3.get(1).text();  //SP段位名
        HSSFWorkbook hssfWorkbook = new HSSFWorkbook();  //创建Excal表
        HSSFSheet hssfSheetDP = hssfWorkbook.createSheet(h32);  //创建名为 :"段位認定 DP(2018) " Excel表
        //设置单元格宽度
        hssfSheetDP .setColumnWidth(1, 8400);
        HSSFCellStyle cellStyle= hssfWorkbook.createCellStyle();
        //设置水平对齐的样式为居中对齐;
        cellStyle.setAlignment(HSSFCellStyle.ALIGN_CENTER);

        //设置字体
        HSSFFont font = hssfWorkbook.createFont();
        font.setFontName("黑体");
        int Th1 = 0;  //列数
        int Tr1 = Tr.size();  //行数

        String star = "";  //小段位星级
        String gradename = "";  //小段位名
        String crossnum = "";  //小合格人数
        String challengesnum = "";  //小挑战人数
        String yield = "";  //小合格率

        String Star = "";  //段位星级
        String GradeName = "";  //段位名
        String CrossNum = "";  //合格人数
        String ChallengesNum = "";  //挑战人数
        String Yield = "";  //合格率

        for (int Tri = 0; Tri < Tr.size(); Tri++) {
            Element TrTitle = Tr.get(Tri);  //第几个Tr框
            Elements Td = TrTitle.getElementsByTag("td");  //合格率等标题 : <th> 其他的时 : <td>
            Elements Th = TrTitle.getElementsByTag("th");
            HSSFRow hssfRow = hssfSheetDP.createRow(Tri);  //在对应的行中填入数据,定位行
            HSSFCell cell1 = hssfRow.createCell(0);  //第rowi行第一个单元格
            HSSFCell cell2 = hssfRow.createCell(1);
            HSSFCell cell3 = hssfRow.createCell(2);
            HSSFCell cell4 = hssfRow.createCell(3);
            HSSFCell cell5 = hssfRow.createCell(4);
            if (Td.size() == 0) {
            }else {
                star = Td.get(0).text();
                gradename = Td.get(1).text();
                crossnum = Td.get(2).text();
                challengesnum = Td.get(3).text();
                yield = Td.get(4).text();
                cell1.setCellValue(star);
                cell2.setCellValue(gradename);
                cell3.setCellValue(crossnum);
                cell4.setCellValue(challengesnum);
                cell5.setCellValue(yield);
            }

            if (Th.size() == 0) {
            }else  {
                Th1 = Th.size();
                Star = Th.get(0).text();
                GradeName = Th.get(1).text();
                CrossNum = Th.get(2).text();
                ChallengesNum = Th.get(3).text();
                Yield = Th.get(4).text();
                cell1.setCellValue(Star);
                cell2.setCellValue(GradeName);
                cell3.setCellValue(CrossNum);
                cell4.setCellValue(ChallengesNum);
                cell5.setCellValue(Yield);
            }
        }


        //表名  : 段位認定 シングル(2018) (h31)
        //项目名 : 1.星级 Star 2.段位名 GradeName 3.合格人数 CrossNum 4.挑战人数 ChallengesNum 5.通过率 Yield
        //行数: Tr1 , 列数 : Th1
        FileOutputStream fos = new FileOutputStream("C:\\Users\\35367\\Desktop\\LR2(DP).xls");  //IO流写入
        hssfWorkbook.write(fos);
        fos.close();
        System.out.println("DPRank创建成功");


    }


}

输出结果:

作者: Xenolies
文章标题 :JAVA爬虫项目学习笔记(Maven框架)
文章链接 : https://xenolies.xyz/2022/05/10/1911/
文章URL : https://xenolies.xyz/2022/05/10/1911/
本文采用 CC BY-NC-SA 4.0 协议
暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇