基于Java爬取微博数据(二) 正文长文本+导出数据Excel

简介: 【5月更文挑战第12天】基于Java爬取微博数据,正文长文本+导出数据Excel

上一篇文章简单讲述了基于Java爬取微博数据(一),那么这篇将Java爬取的微博数据导出到Excel中。下面开始具体的操作。

长文本补全

在爬取微博数据的时候,大家可能不太会注意到这样的微博数据,比如

image.png

这样的文本数据有什么特点呢?直观的可以看到 在微博正文结束 出现了【展开】字样,那么这样的微博内容通过Java爬取数据获取到的 text 字段的取值内容是这样的

text:#伊朗将宣布总统莱希等遇难人员葬礼安排#据伊朗国家电视台报道,伊朗政府内阁举行了特别会议,将会宣布伊朗总统莱希等遇难人员的葬礼安排。#伊朗总统莱希等高级官员遇难#据伊朗官方通讯社报道,莱希5月19日在伊朗东阿塞拜疆省出席一个大坝的落成仪式后,其所乘坐的直升机在返回大不里士的途中失事, ​​​ ...展开

可以看到 text 字段同样返回的内容是有 【展开】 字样的,那么按常理看,微博正文内容肯定时没有获取完整的。那么这个时候就需要补齐长文本了。


在微博页面点击【展开】可以看到,触发了ajax 方法 https://weibo.com/ajax/statuses/longtext?id=Of8PMwTSJ  获取微博内容详情并补足内容展示

image.png

参数 id=Of8PMwTSJ 来自于 爬取微博数据请求链接 https://weibo.com/ajax/statuses/mymblog?uid=1686546714&page=1&feature=0  返回的数据

image.png

下面对于有 ...展开 字样的微博内容,往往就是需要补足微博长文本内容的,那么可以在代码中增加如下内容

//有一种情况,就是当页面文本内容过多的时候,微博默认不展示全部,而是出现 【...展示】 按钮,此时需要再请求一个 URL 获取展开后的文本内容
if (text.lastIndexOf("...展开") != -1) {
    //说明存在 展开 需要重新获取 text 内容
    String mblogid = data.getString("mblogid");
    // 格式化URL并发送HTTP请求获取响应
    String unfoldurlstr = String.format(unfoldurl, mblogid);
    HttpResponse response2 = HttpUtil.createGet(unfoldurlstr)
        .header("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36")
        .header("Cookie",cookie)
        .execute();
    // 如果没有长文本内容会返回 {"ok": 1,"http_code": 200,"data": {}}
    String body2 = response2.body();
    JSONObject jsonObject2 = JSONObject.parseObject(body2).getJSONObject("data");
    String longTextContent = jsonObject2.getString("longTextContent");
    System.out.println("longTextContent:"+longTextContent);
}

其中,cookie和在爬取微博正文内容时用的是同一个cookie,再次执行main函数看到如下内容

image.png

导出微博数据到Excel

补全了微博正文内容后,就可以进行下一步操作了,将爬取的微博数据导出到Excel中去,那么首先需要引入 Excel 相关操作 jar 包 ,pom.xml 文件增加

<dependency>
  <groupId>com.alibaba</groupId>
  <artifactId>easyexcel</artifactId>
  <version>3.0.5</version>
</dependency>

然后根据所需字段创建导出微博数据的实体对象类  ExcelData.java

package com.ruoyi.web.controller.demo.controller;

import com.alibaba.excel.annotation.ExcelProperty;

import java.util.Date;

/**
 * dongao
 * 2024/4/23
 * 4月
 */
public class ExcelData {
    @ExcelProperty("发布日期")
    private Date date;
    @ExcelProperty("内容")
    private String content;
    @ExcelProperty("点赞")
    private Long like;
    @ExcelProperty("评论")
    private Long comment;
    @ExcelProperty("转发")
    private Long repost;

    public Date getDate() {
        return date;
    }

    public void setDate(Date date) {
        this.date = date;
    }

    public Long getLike() {
        return like;
    }

    public void setLike(Long like) {
        this.like = like;
    }

    public Long getComment() {
        return comment;
    }

    public void setComment(Long comment) {
        this.comment = comment;
    }

    public Long getRepost() {
        return repost;
    }

    public void setRepost(Long repost) {
        this.repost = repost;
    }

    public String getContent() {
        return content;
    }

    public void setContent(String content) {
        this.content = content;
    }
}

最后就是改造 main 函数,增加导出数据操作,改造后的 main 函数结构如下

image.png

for 循环内部需要增加写入 对象 ExcelData 并放入导出列表的代码,

image.png

那么最后改造后的 main 函数的全部代码 如下

package com.ruoyi.web.controller.demo.controller;

import cn.hutool.http.HttpResponse;
import cn.hutool.http.HttpUtil;
import com.alibaba.excel.EasyExcel;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Objects;

public class DemoWeiBo
{
     /**
     * 主函数入口,用于从微博抓取数据并存储到Excel中。
     *
     * @param args 命令行参数(未使用)
     * @throws ParseException 当日期解析发生错误时抛出
     */
    public static void main(String[] args) throws ParseException {
        // 定义微博数据抓取的URL模板
        String url = "https://weibo.com/ajax/statuses/mymblog?uid=1686546714&feature=0&page=%s";
        String unfoldurl = "https://weibo.com/ajax/statuses/longtext?id=%s";
        String cookie = "你的cookie";

        // 初始化日期格式
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        //初始化导出Excel数据列表
        List<ExcelData> excelDataList = new ArrayList<>();

        // 循环抓取前2页数据
        for (int i = 1; i <= 2; i++) {
            try {
                // 输出开始抓取的提示信息
                System.out.println("开始获取第" + i + "页数据");

                // 格式化URL并发送HTTP请求获取响应
                String urlstr = String.format(url, i);
                HttpResponse response = HttpUtil.createGet(urlstr)
                        .header("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36")
                        .header("Cookie",cookie)
                        .execute();

                // 解析响应体
                String body = response.body();
                //System.out.println(body);

                JSONObject jsonObject = JSONObject.parseObject(body).getJSONObject("data");
                JSONArray list = null;
                if (Objects.nonNull(jsonObject)) {
                    // 处理数据列表
                    list = jsonObject.getJSONArray("list");

                    // 遍历并处理每条微博数据
                    for (Object o : list) {
                        JSONObject data = (JSONObject) o;
                        // 解析并处理微博的其他信息
                        Date created = new Date(data.getString("created_at"));
                        System.out.println("created:"+dateFormat.format(created));
                        String regex = "<[^<>]*>";
                        String text = data.getString("text").replaceAll(regex, "");
                        System.out.println("text:"+text);
                        String repost = data.getString("reposts_count");
                        System.out.println("repost:"+repost);
                        String comment = data.getString("comments_count");
                        System.out.println("comment:"+comment);
                        String like = data.getString("attitudes_count");
                        System.out.println("like:"+like);

                        //有一种情况,就是当页面文本内容过多的时候,微博默认不展示全部,而是出现 【...展示】 按钮,此时需要再请求一个 URL 获取展开后的文本内容
                        if (text.lastIndexOf("...展开") != -1) {
                            //说明存在 展开 需要重新获取 text 内容
                            String mblogid = data.getString("mblogid");
                            // 格式化URL并发送HTTP请求获取响应
                            String unfoldurlstr = String.format(unfoldurl, mblogid);
                            HttpResponse response2 = HttpUtil.createGet(unfoldurlstr)
                                    .header("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36")
                                    .header("Cookie",cookie)
                                    .execute();
                            // {"ok": 1,"http_code": 200,"data": {}}
                            String body2 = response2.body();
                            JSONObject jsonObject2 = JSONObject.parseObject(body2).getJSONObject("data");
                            String longTextContent = jsonObject2.getString("longTextContent");
                            System.out.println("longTextContent:"+longTextContent);
                            //补全后的内容赋给 text
                            text = longTextContent;
                        }

                        // 创建ExcelData对象并填充数据
                        ExcelData excelData = new ExcelData();
                        excelData.setDate(created);
                        excelData.setLike(Long.parseLong(like));
                        excelData.setComment(Long.parseLong(comment));
                        excelData.setRepost(Long.parseLong(repost));
                        excelData.setContent(text);
                        excelDataList.add(excelData);
                    }
                }

                // 输出完成提示并关闭响应,休眠以避免频繁请求
                System.out.println("第" + i + "页数据获取完毕");
                response.close();
                // 如果列表为空,终止循环
                if (list == null || list.size() == 0) {
                    break;
                }
                Thread.sleep(700);
            } catch (Exception e) {
                // 打印异常信息
                e.printStackTrace();
            }
        }

        // 输出开始写入Excel的提示
        System.out.println("Excel写入数据开始");
        // 写入Excel的函数调用
        EasyExcel.write("E:/微博.xlsx", ExcelData.class)
                .sheet("Sheet1")
                .doWrite(excelDataList);
        System.out.println("Excel写入数据结束");
    }
}

执行 main 函数,执行完成之后,看到已经成功导出到Excel 中

image.png

打开我们指定目录下的 Excel 文件

image.png

这里可以看到我们已经用再次获取的长文本内容替换了原始文本内容,补足内容了。

到这里,基于 Java 爬取微博数据,并补充长文本微博正文内容,导出微博数据到 Excel 表格的操作就完成了。

注意点

这里需要说明的是,本文主要是探索基于 Java 爬取微博数据,并补充长文本微博正文内容,导出微博数据到 Excel 表格等相关内容实现,大家有需要的可以相互学习一下。但是注意不可用于非法用途,远离“破坏计算机信息系统罪”,慎重!慎重!慎重!

相关文章
|
18天前
|
Java 程序员 容器
Java中的变量和常量:数据的‘小盒子’和‘铁盒子’有啥不一样?
在Java中,变量是一个可以随时改变的数据容器,类似于一个可以反复打开的小盒子。定义变量时需指定数据类型和名称。例如:`int age = 25;` 表示定义一个整数类型的变量 `age`,初始值为25。 常量则是不可改变的数据容器,类似于一个锁死的铁盒子,定义时使用 `final` 关键字。例如:`final int MAX_SPEED = 120;` 表示定义一个名为 `MAX_SPEED` 的常量,值为120,且不能修改。 变量和常量的主要区别在于变量的数据可以随时修改,而常量的数据一旦确定就不能改变。常量主要用于防止意外修改、提高代码可读性和便于维护。
|
18天前
|
存储 缓存 安全
在 Java 编程中,创建临时文件用于存储临时数据或进行临时操作非常常见
在 Java 编程中,创建临时文件用于存储临时数据或进行临时操作非常常见。本文介绍了使用 `File.createTempFile` 方法和自定义创建临时文件的两种方式,详细探讨了它们的使用场景和注意事项,包括数据缓存、文件上传下载和日志记录等。强调了清理临时文件、确保文件名唯一性和合理设置文件权限的重要性。
42 2
|
18天前
|
Java
Java 8 引入的 Streams 功能强大,提供了一种简洁高效的处理数据集合的方式
Java 8 引入的 Streams 功能强大,提供了一种简洁高效的处理数据集合的方式。本文介绍了 Streams 的基本概念和使用方法,包括创建 Streams、中间操作和终端操作,并通过多个案例详细解析了过滤、映射、归并、排序、分组和并行处理等操作,帮助读者更好地理解和掌握这一重要特性。
25 2
|
23天前
|
存储 分布式计算 Java
存算分离与计算向数据移动:深度解析与Java实现
【11月更文挑战第10天】随着大数据时代的到来,数据量的激增给传统的数据处理架构带来了巨大的挑战。传统的“存算一体”架构,即计算资源与存储资源紧密耦合,在处理海量数据时逐渐显露出其局限性。为了应对这些挑战,存算分离(Disaggregated Storage and Compute Architecture)和计算向数据移动(Compute Moves to Data)两种架构应运而生,成为大数据处理领域的热门技术。
40 2
|
29天前
|
存储 Java API
Java实现导出多个excel表打包到zip文件中,供客户端另存为窗口下载
Java实现导出多个excel表打包到zip文件中,供客户端另存为窗口下载
37 4
|
29天前
|
SQL Java OLAP
java实现“数据平滑升级”
java实现“数据平滑升级”
42 2
|
Java C语言 C++
Java 的数据类型划分(数据类型划分)| 学习笔记
快速学习 Java 的数据类型划分(数据类型划分)
125 0
Java 的数据类型划分(数据类型划分)| 学习笔记
|
Java 开发者 Windows
Java 数据类型划分(字符型)|学习笔记
快速学习 Java 数据类型划分(字符型)
128 0
|
Java 开发者
Java 数据类型划分(整型类型)|学习笔记
快速学习 Java 数据类型划分(整型类型)
100 0
|
Java 开发者
Java 数据类型划分(初见 String 类)|学习笔记
快速学习 Java 数据类型划分(初见 String 类)
100 0