Java 使用 EasyExcel 爬取数据

一、爬取数据的基本思路

分析要爬取数据的来源

  1. **查找数据来源:**浏览器按 F12 或右键单击"检查"打开开发者工具查看数据获取时的请求地址

2.**查看接口信息:**复制请求地址直接到浏览器地址栏输入看能不能取到数据

  1. 推荐安装插件:FeHelper(FeHelper - Awesome

  2. 按 F12 打开控制台,查看网络请求,复制 curl 代码便于查看和执行:

注意不要暴露 cookie!!

java 复制代码
curl "https://api.zsxq.com/v2/hashtags/48844541281228/topics?count=20" ^
  -H "authority: api.zsxq.com" ^
  -H "accept: application/json, text/plain, */*" ^
  -H "accept-language: zh-CN,zh;q=0.9" ^
  -H "cache-control: no-cache" ^
  -H "origin: https://wx.zsxq.com" ^
  -H "pragma: no-cache" ^
  -H "referer: https://wx.zsxq.com/" ^
  --compressed

二、使用 EasyExcel 爬取数据

方式一:通过监听器读取

  1. 导入 EasyExcel 的依赖
XML 复制代码
<!-- https://mvnrepository.com/artifact/com.alibaba/easyexcel -->
<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>easyexcel</artifactId>
    <version>3.1.1</version>
</dependency>
  1. 创建读对象

读对象的的两种方式:

  • 表头确定:创建对象(属性即为需要的列数据)

  • 表头不确定:把每一行数据映射为 Map<String, Object>

  • 本系统的表头是确定的,读取表格中的用户名及星球编号即可,所以使用创建对象,对象的属性与表头进行绑定即可

  • 将 Excel 表格字段与 Java 对象关联起来:使用 @ExcelProperty("") 注解指定使用 index 强制匹配或根据 "str" 字符串匹配表格数据
java 复制代码
package com.example.usercenter.once;

import com.alibaba.excel.annotation.ExcelProperty;
import lombok.Data;

/**
 * 用户信息实体对象:与 Excel 字段对应
 * @author Ghost
 * @version 1.0
 */
@Data
public class TableUserData {

    @ExcelProperty("用户名")
    private String username;

    @ExcelProperty("星球编号")
    private String planetCode;

}
  1. 读取数据:先创建监听器,在读取数据时绑定监听器
  • 实现监听器 ReadListener 接口的 invoke() 方法,读取数据时会触发该方法
  • 实现 doAfterAllAnalysed() 方法,当所有数据读取完成就会触发一次该方法
  • 单独抽离处理逻辑,代码清晰易于维护
  • 一条一条处理,适用于数据量大的场景
java 复制代码
package com.example.usercenter.once;

import com.alibaba.excel.context.AnalysisContext;
import lombok.extern.slf4j.Slf4j;
import com.alibaba.excel.read.listener.ReadListener;

@Slf4j
public class DemoDataListener implements ReadListener<TableUserData> {

    /**
     * 这个每一条数据解析都会来调用
     *
     * @param data    one row value. Is is same as {@link AnalysisContext#readRowHolder()}
     * @param context
     */
    @Override
    public void invoke(TableUserData data, AnalysisContext context) {
        System.out.println(data);// 输出每次解析到的数据
    }

    /**
     * 所有数据解析完成了 都会来调用
     *
     * @param context
     */
    @Override
    public void doAfterAllAnalysed(AnalysisContext context) {
        log.info("所有数据解析完成!");
    }
}
  1. 绑定监听器,读取 Excel 数据
  • 在 resources 目录下新建一个 testUser.xls 作为测试使用
  • 绑定监听器 DemoDataListener
  • 每次解析一条数据,每次解析都会调用 invoke() 方法输出数据
java 复制代码
package com.example.usercenter.once;

import com.alibaba.excel.EasyExcel;

/**
 * 读取 Excel 表格数据
 * @author Ghost
 * @version 1.0
 */
public class ImportExcelData {
    public static void main(String[] args) {
        // 写法 1
        String fileName = "D:\\code\\user-center\\src\\main\\resources\\testUser.xls";// 先写一个绝对路径
        // 这里默认每次会读取100条数据 然后返回过来 直接调用使用数据就行
        EasyExcel.read(fileName, TableUserData.class, new DemoDataListener()).sheet().doRead();
    }

}
  1. 运行程序,查看效果

方式二:使用同步读方式

  1. 导入 EasyExcel 的依赖(同方式一)

  2. 创建读对象(同方式一)

  3. 读取数据:使用同步读的方式

  • 无需创建监听器,一次性获取完整数据
  • 方便简单,但数据量大时需要等待,会卡顿
java 复制代码
package com.example.usercenter.once;

import com.alibaba.excel.EasyExcel;
import lombok.extern.slf4j.Slf4j;

import java.util.List;

/**
 * 读取 Excel 表格数据
 * @author Ghost
 * @version 1.0
 */
@Slf4j
public class ImportExcelData {
    public static void main(String[] args) {
        // 写法 1
        String fileName = "D:\\code\\user-center\\src\\main\\resources\\testUser.xls";// 先写一个绝对路径
//        readByListener(fileName);
        synchronousRead(fileName);
    }

    /**
     * 读取方式一:使用监听器读取
     * @param fileName 文件路径
     */
    public static void readByListener(String fileName) {
        // 这里默认每次会读取100条数据 然后返回过来 直接调用使用数据就行
        EasyExcel.read(fileName, TableUserData.class, new DemoDataListener()).sheet().doRead();
    }

    /**
     * 读取方式二:同步读取(同步的返回,不推荐使用,如果数据量大会把数据放到内存里面)
     * @param fileName 文件路径
     */
    public static void synchronousRead(String fileName) {
        // 这里 需要指定读用哪个class去读,然后读取第一个sheet 同步读取会自动finish
        List<TableUserData> list = EasyExcel.read(fileName).head(TableUserData.class).sheet().doReadSync();
        for (TableUserData data : list) {
            log.info("读取到数据:{}", data);
        }
    }

}
  1. 运行程序,查看效果

三、清洗数据后导入数据库

  1. 使用同步读的方式获取数据

  2. 数据去重:判断是否有用户名相同的用户

  3. TODO:如何获取所有用户(用户的唯一标识)

相关推荐
李慕婉学姐5 分钟前
Springboot养老服务管理系统c0t92vu6(程序+源码+数据库+调试部署+开发环境)带论文文档1万字以上,文末可获取,系统界面在最后面。
数据库·spring boot·后端
rell3366 分钟前
机顶盒播放udp/rtp马赛克
java·网络·网络协议·udp
Arya_aa8 分钟前
多个对象通过集合实现io流的读写
java
霖霖总总10 分钟前
[Redis小技巧10]深入 Redis Stream:从原理到生产级实践
数据库·redis
白云如幻17 分钟前
【JDBC】集合、反射和泛型复习-3
java·开发语言·jdbc
tang7778925 分钟前
哪些行业用动态代理ip?哪些行业用静态代理IP?怎样区分动态ip和静态ip?(互联网人必码·实用长文)
大数据·网络·爬虫·python·网络协议·tcp/ip·智能路由器
扑克中的黑桃A37 分钟前
基于代价模型的连接条件下推:复杂SQL查询的性能优化实践
数据库
数据知道38 分钟前
MongoDB分片集群监控:详解Balancer状态与Chunk分布分析
数据库·mongodb
tang7778942 分钟前
爬虫代理IP池到底有啥用?
网络·爬虫·python·网络协议·tcp/ip·ip
冬夜戏雪1 小时前
实习面经摘录(六)
java