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

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

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

长文本补全

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

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

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

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

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

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

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

java 复制代码
//有一种情况,就是当页面文本内容过多的时候,微博默认不展示全部,而是出现 【...展示】 按钮,此时需要再请求一个 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函数看到如下内容

导出微博数据到Excel

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

xml 复制代码
<dependency>
  <groupId>com.alibaba</groupId>
  <artifactId>easyexcel</artifactId>
  <version>3.0.5</version>
</dependency>

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

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 函数结构如下

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

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

java 复制代码
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 中

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

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

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

注意点

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

相关推荐
重生之我在20年代敲代码29 分钟前
strncpy函数的使用和模拟实现
c语言·开发语言·c++·经验分享·笔记
爱上语文30 分钟前
Springboot的三层架构
java·开发语言·spring boot·后端·spring
serve the people34 分钟前
springboot 单独新建一个文件实时写数据,当文件大于100M时按照日期时间做文件名进行归档
java·spring boot·后端
qmx_071 小时前
HTB-Jerry(tomcat war文件、msfvenom)
java·web安全·网络安全·tomcat
为风而战2 小时前
IIS+Ngnix+Tomcat 部署网站 用IIS实现反向代理
java·tomcat
编程零零七3 小时前
Python数据分析工具(三):pymssql的用法
开发语言·前端·数据库·python·oracle·数据分析·pymssql
技术无疆4 小时前
快速开发与维护:探索 AndroidAnnotations
android·java·android studio·android-studio·androidx·代码注入
2401_858286114 小时前
52.【C语言】 字符函数和字符串函数(strcat函数)
c语言·开发语言
铁松溜达py4 小时前
编译器/工具链环境:GCC vs LLVM/Clang,MSVCRT vs UCRT
开发语言·网络
everyStudy4 小时前
JavaScript如何判断输入的是空格
开发语言·javascript·ecmascript