Java语言爬虫并将网页数据自动导出Excel

一、利用爬虫工具爬取网页数据

JSoup是一个用于解析、操作和提取HTML和XML文档数据的Java库。它主要用于Web抓取,特别是在需要从网页中提取数据、进行数据挖掘或网页分析时非常有用。它提供了简单而强大的API,使得在Java中进行网页爬取和数据提取变得更加容易。以下是JSoup的一些主要特性和用法:

(一) Jsoup 主要特性:

1. 解析HTML和XML:

JSoup能够解析HTML和XML文档,支持从URL、文件、字符串等不同来源加载文档。

2. DOM操作:

JSoup提供了类似于JavaScript中的DOM操作方式,可以轻松地遍历文档树、选择特定的元素或节点,并进行增删改查操作。

3. CSS选择器:

类似于jQuery,JSoup支持使用CSS选择器来定位和选取文档中的元素,方便快捷地提取目标数据。

4. 清理和转换HTML:

JSoup能够处理不规范的HTML,可以清理文档、格式化输出或将HTML转换为纯文本。

5. HTTP请求:

虽然主要是HTML解析库,但JSoup也可以用来发送HTTP请求并获取网页内容,方便进行网页抓取。

6. 安全性考虑:

JSoup能够防范跨站脚本攻击(XSS),它提供了API来清理用户提供的HTML内容,以保护应用程序免受恶意攻击。

(二)利用Jsoup爬取网页数据

1. pom文件导入依赖

首先新建一个空的springboot工程项目,然后导入爬虫工具Jsoup所需要的依赖包,再进行maven构建。

// Jsoup依赖包
<dependency>
    <groupId>org.jsoup</groupId>
    <artifactId>jsoup</artifactId>
    <version>1.14.3</version>
</dependency>

2. 爬虫核心代码

import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
import java.io.IOException;

public class JsoupExample {
    public static void main(String[] args) {
        try {

            String url = "网址URL";

            // 发送HTTP GET请求并获取网页内容
            Document document = (Document) Jsoup.connect(url).get();

            // 获取网页标题
            String title = document.title();
            System.out.println("网页标题:" + title);
            System.out.println("-----------------------------------------------");
			
			// 获取网页内带有“a[href]”标签的内容
			Elements links = document.select("a[href]");
            System.out.println("链接数量:" + links.size());
            
            // 打印每个链接的文本和URL
            for (Element link : links) {
             	//获取HTML元素<a>中的文本内容
                String linkText = link.text(); 
                //获取HTML元素<a>中href属性的值
                String linkUrl = link.attr("href");
                System.out.println("链接文本:" + linkText);
                System.out.println("链接URL:" + linkUrl);
            }
            
            // 获取网页内带有“td”标签的的内容
            Elements contents = document.select("td");
            System.out.println("内容数量:" + contents.size());
            System.out.println("-----------------------------------------------");
			
            // 数据整理(自定义的方法,根据自己的实际情况编写)
            Map<String, String> collatedData = DataCollation.dataCollation(contents);

            // 打印整理后的数据
            for (Map.Entry<String, String> entry : collatedData.entrySet()) {
                System.out.println(entry.getKey() + ": " + entry.getValue());
            }

        } catch (IOException e) {
            e.printStackTrace();
        }
}

3. 常见问题解决

在进行网页数据爬取的时候,还可能会出现下面的报错问题:

javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
	at sun.security.ssl.Alerts.getSSLException(Alerts.java:192)
	at sun.security.ssl.SSLSocketImpl.fatal(SSLSocketImpl.java:1949)
	at sun.security.ssl.Handshaker.fatalSE(Handshaker.java:302)
	at sun.security.ssl.Handshaker.fatalSE(Handshaker.java:296)
	at sun.security.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:1514)
	at sun.security.ssl.ClientHandshaker.processMessage(ClientHandshaker.java:216)
	at sun.security.ssl.Handshaker.processLoop(Handshaker.java:1026)
	at sun.security.ssl.Handshaker.process_record(Handshaker.java:961)
	at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:1062)
	at sun.security.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1375)
	at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1403)
	at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1387)
	at sun.net.www.protocol.https.HttpsClient.afterConnect(HttpsClient.java:559)
	at sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.connect(AbstractDelegateHttpsURLConnection.java:185)
	at sun.net.www.protocol.https.HttpsURLConnectionImpl.connect(HttpsURLConnectionImpl.java:153)
	at org.jsoup.helper.HttpConnection$Response.execute(HttpConnection.java:859)
	at org.jsoup.helper.HttpConnection$Response.execute(HttpConnection.java:829)
	at org.jsoup.helper.HttpConnection.execute(HttpConnection.java:366)
	at org.jsoup.helper.HttpConnection.get(HttpConnection.java:353)
	at org.example.utils.JsoupExample.main(JsoupExample.java:22)
Caused by: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
	at sun.security.validator.PKIXValidator.doBuild(PKIXValidator.java:387)
	at sun.security.validator.PKIXValidator.engineValidate(PKIXValidator.java:292)
	at sun.security.validator.Validator.validate(Validator.java:260)
	at sun.security.ssl.X509TrustManagerImpl.validate(X509TrustManagerImpl.java:324)
	at sun.security.ssl.X509TrustManagerImpl.checkTrusted(X509TrustManagerImpl.java:229)
	at sun.security.ssl.X509TrustManagerImpl.checkServerTrusted(X509TrustManagerImpl.java:124)
	at sun.security.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:1496)
	... 15 more
Caused by: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
	at sun.security.provider.certpath.SunCertPathBuilder.build(SunCertPathBuilder.java:141)
	at sun.security.provider.certpath.SunCertPathBuilder.engineBuild(SunCertPathBuilder.java:126)
	at java.security.cert.CertPathBuilder.build(CertPathBuilder.java:280)
	at sun.security.validator.PKIXValidator.doBuild(PKIXValidator.java:382)
	... 21 more
问题分析

经过研究,发现这个错误其实是由于在与网页进行SSL/TLS 握手的过程中出现了证书问题导致的。可能是由于远程主机的 SSL 证书无法验证,或者本地 Java 证书存储中缺少必要的证书而导致的。在运行你的 Java 应用程序之前,需要将缺失的证书导入到 Java 证书存储中。

问题解决
a. 在谷歌浏览器中访问目标网站并点击网址链接旁边的符号,查看证书信息。
b. 导出目标网站的证书文件。
c. 在 Java 的证书存储中导入该证书。使用 keytool 命令完成此操作。
注意要在Java本地安装路径JDK文件夹的 bin文件夹路径下打开命令行窗口,因为这里才有keytool工具。

keytool导入指定证书

 keytool -importcert -file 证书文件本地路径 -keystore JDK本地安装路径\jre\lib\security\cacerts -storepass changeit

参数解释:

keytool -importcert :keytool导入证书命令
-storepass:参数用于指定证书存储的密码。对于默认的 Java 证书存储(cacerts),默认密码为 changeit。

将SSL证书加入到Java证书存储库之后,再次运行代码就可以爬取网址指定信息了

二、网页数据自动导出Excel

爬取完所有数据之后,我们可以利用SpringBoot框架的基本操作,创建针对数据的实体类,然后将其存放到数据库表里,现在需要将数据库表中的数据导出成Excel。经过技术探索,最终选择了 Alibaba 的 EasyExcel 库,配合@ExcelProperty注解,简便高效!!

(一)pom文件导入依赖

<!-- easyExcel-->
<dependency>
  <groupId>com.alibaba</groupId>
  <artifactId>easyexcel</artifactId>
  <version>3.1.1</version>
</dependency>

(二) 创建数据Vo类并添加@ExcelProperty注解

创建Vo类的目的就是为了更规范的显示数据库数据,这里加上==@ExcelProperty==注解,可以设置该属性导出成Excel之后的列名。这样一来,导出的Excel数据就可以自动添加列名。

Alt

(三)数据导出Excel的controller接口方法

/**
 * 将数据导出Excel
 * @param response
 * @throws IOException
 */
@GetMapping("/exportExcel")
public void exportExcel(HttpServletResponse response) throws IOException {

    // 数据vo列表,该Vo类的属性已经添加了@ExcelProperty注解
    // 这里写了一个service方法,来获取数据库表中存入的所有爬取数据
    List<PublicityReportVo> dataList = publicityReportService.getAllData();

    // 设置响应头
    String filename = "导出的文件名";
    response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
    response.setHeader("Content-Disposition", "attachment; filename="+filename+".xlsx");

    // 使用EasyExcel直接写入数据,自动映射刚才写的数据Vo类
    // 它会自动处理列名,这里设置表单名为 Data
    EasyExcel.write(response.getOutputStream(), PublicityReportVo.class)
    .sheet("Data")  
    .doWrite(dataList);
}

这里需要特别注意的是,一定要设置响应头,因为这里可以指定输出的文件格式,如果不设置的话,输出的文件就可能会是zip格式的,会很奇怪!!

Alt

最后,启动controller服务,在网页中输入接口的访问地址,就可以在网页里自动下载,得到我们想要的Excel文件啦!!!!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值