基于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 表格等相关内容实现,大家有需要的可以相互学习一下。但是注意不可用于非法用途,远离“破坏计算机信息系统罪”,慎重!慎重!慎重!

相关文章
|
2天前
|
缓存 NoSQL Java
Java高并发实战:利用线程池和Redis实现高效数据入库
Java高并发实战:利用线程池和Redis实现高效数据入库
12 0
|
3天前
|
Java Maven
Java 怎样从 excel 中读取文件、写入文件
Java 怎样从 excel 中读取文件、写入文件
10 0
|
4天前
|
JSON Java 数据格式
java读取接口返回的json数据 (二)
java读取接口返回的json数据 (二)
17 5
|
4天前
|
JSON Java 数据格式
java读取接口返回的json数据
java读取接口返回的json数据
17 5
|
4天前
|
安全 Java 程序员
Java8实战-用流收集数据
Java8实战-用流收集数据
7 0
|
1月前
|
Java
java导出复杂excel
java导出复杂excel
|
2天前
|
JavaScript 前端开发
JS导出excel功能
JS导出excel功能
|
10天前
|
前端开发
react框架对Excel文件进行上传和导出
react框架对Excel文件进行上传和导出
|
12天前
|
前端开发
React实现一个excel文件导出
React实现一个excel文件导出
16 0
分享:2秒快速查询40万手机号码归属地,批量手机号码归属地查询可以导出excel表格,WPS表格查询手机号码归属地怎么操作,批量手机号码归属地批量查询软件,批量号码查询按省份和城市分类,按运移动号码电信号码联通号码分类整理
本文介绍了如何批量快速查询手机号码归属地并进行分类。首先,通过提供的百度网盘或腾讯云盘链接下载免费查询软件。其次,开启软件,启用复制粘贴功能,直接粘贴号码列表并选择高速查询。软件能在极短时间内(如1.76秒内)完成40多万个号码的查询,结果包括归属地、运营商、邮箱和区号,且数据准确。之后,可直接导出数据至表格,若数据超过100万,可按省份、城市及运营商分类导出。文章还附带了操作动画演示,展示全程流畅的处理大量手机号码归属地查询的过程。
分享:2秒快速查询40万手机号码归属地,批量手机号码归属地查询可以导出excel表格,WPS表格查询手机号码归属地怎么操作,批量手机号码归属地批量查询软件,批量号码查询按省份和城市分类,按运移动号码电信号码联通号码分类整理