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

news/2024/11/13 9:16:31/

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

  • 长文本补全
  • 导出微博数据到Excel
  • 注意点

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

长文本补全

在爬取微博数据的时候,大家可能不太会注意到这样的微博数据,比如
在这里插入图片描述
这样的文本数据有什么特点呢?直观的可以看到 在微博正文结束 出现了【展开】字样,那么这样的微博内容通过Java爬取数据获取到的 text 字段的取值内容是这样的

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 文件增加

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


http://www.ppmy.cn/news/1512794.html

相关文章

Q*算法深度猜猜:从Q-learning优化到智能决策

Q*算法深度猜猜&#xff1a;从Q-learning优化到智能决策 引言 在强化学习&#xff08;Reinforcement Learning&#xff09;中&#xff0c;Q-learning算法作为一种无模型的学习方法&#xff0c;被广泛应用于解决各种决策优化问题。然而&#xff0c;尽管Q-learning在许多场景下…

C语言:递归

递归简单来说就是函数自己调用自己。 特点&#xff1a;一般代码比较简洁&#xff0c;没有出口。 例子1&#xff1a;用一个函数计算阶乘 #include<stdio.h>//不用递归 int fac(int n) {int val 1;for (int i 1; i <n;i){val * i;}return val; }//用递归 int fac1(…

面试题目:(6)翻转二叉树

题目 翻转二叉树 &#xff08;中间对称翻转&#xff0c;等于镜像&#xff09;给你一棵二叉树的根节点 root &#xff0c;翻转这棵二叉树&#xff0c;并返回其根节点。示例1&#xff1a; 输入&#xff1a;root [4,2,7,1,3,6,9]输出&#xff1a;[4,7,2,9,6,3,1]示例1&#xff1…

2024 NVIDIA Summer Camp Day1:构建RAG多模态AI Agent

下载材料和课件等 课程相关资料下载链接: https://pan.baidu.com/s/15Y-gmsfeYCgKF-M3TJZVgg?pwdfafe 提取码: fafe 1.课件 链接&#xff1a;https://pan.baidu.com/s/15JTy9CqnesXSlPiwwrUmjA?pwd1111 提取码&#xff1a;1111 2.phi3量化大模型 链接&#xff1a;http…

vivado中出现ERROR: [Labtools 27-2220]检测不出开发板

emmm,解决方法&#xff0c;重启电脑&#xff0c;再重新打开vivado&#xff0c;然后电脑会弹窗问允不允许vivado使用网络&#xff0c;同意后&#xff0c;就可以检测出来了。 verilog中出现ERROR: [Labtools 27-2220] Launch Error: Unable to launch local cs_server executable…

CSS的:current伪类:精准定位当前活动元素

CSS&#xff08;层叠样式表&#xff09;是控制网页样式的核心语言。随着CSS4的提出&#xff0c;一系列新的选择器被引入&#xff0c;其中:current伪类便是这些新特性之一。:current伪类允许开发者选择当前处于活动状态的元素&#xff0c;这在创建动态和交互性网页时非常有用。本…

linux容器基础-namespace-3(pid)

pid namespace pid namespace表示隔离一个具有独立PID的运行环境。 在每一个pid namespace中&#xff0c;进程的pid都从1开始&#xff0c;且和其他pid namespace中的PID互不影响。 这意味着&#xff0c;不同pid namespace中可以有相同的PID值。 在介绍pid namespace之前&#…

docker使用的一些坑

docker使用的一些坑 1、Centos7安全Selinux禁止了一些安全权限&#xff0c;导致mysql和mariadb在进行挂载/var/lib/mysql时&#xff0c;容器无法启动&#xff0c;三个解决方案 &#xff08;1&#xff09;在docker run中加入 –privilegedtrue 给容器加上特定权限 如原命令 d…