前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >基于Java爬取微博数据(二) 正文长文本+导出数据Excel

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

原创
作者头像
六月的雨在Tencent
发布2024-09-22 10:12:58
2420
发布2024-09-22 10:12:58
举报
文章被收录于专栏:创作是最好的自我投资

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

需求背景

通常情况下,你爬取数据并不是为了证明你懂或者你会爬取数据,当然也不是为了图一乐来爬取数据。爬取数据的目的呢,往往都是需要基于现有的数据进行分析整理,从而筛选出有价值的信息用于后续的业务处理。在爬取数据的过程中,发现了微博对于一些长文本在展示时有一些截断操作,也就是说页面上你看到的微博长文本并不是一次加载出来,而是通过点击【展开】后补充加载出来的,那么在爬取数据时,为了保障数据内容的完整性,就需要先补充一下长文本内容。

长文本补全

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

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

代码语言:txt
复制
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 表格等相关内容实现,大家有需要的可以相互学习一下。在爬取数据时,仍需保证在不影响微博服务稳定性的情况下测试,不要盲目操作。注意不可用于非法用途,远离“破坏计算机信息系统罪”,慎重!慎重!慎重!

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 需求背景
  • 长文本补全
  • 导出微博数据到Excel
  • 注意点
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档