网站建设一条龙,做网站买完域名还要,天津网站建设排名,网站源码上传基于Java爬取微博数据五 补充微博正文列表图片 or 视频 内容 数据分析补充图片 or 视频执行结果 在通过对微博正文内容中的图片 or 视频内容进行分析后#xff0c;图片 or 视频 链接是可以直接通过 Java 代码下载或者转存的#xff0c;那么这样就可以补充我们在 【基于Java爬… 基于Java爬取微博数据五 补充微博正文列表图片 or 视频 内容 数据分析补充图片 or 视频执行结果 在通过对微博正文内容中的图片 or 视频内容进行分析后图片 or 视频 链接是可以直接通过 Java 代码下载或者转存的那么这样就可以补充我们在 【基于Java爬取微博数据(一) 微博主页正文列表数据】 时缺失的图片 or 视频信息了当然如果你的需求并不需要转存微博正文列表内容中的图片 or 视频的话那么你就无需进行下面的操作了。在开始进行微博主页正文列表数据 补充 图片 or 视频内容之前先来分析一下获取到的微博正文列表数据的内容。
数据分析
同样的我们先找到获取微博正文列表数据的 ajax 请求 /ajax/statuses/mymblog?uid1686546714page1feature0 的响应返回数据 获取到微博正文列表请求响应返回的数据之后我从中取出一个含图片的完整的微博正文 json 对象 以及 一个含视频的完整的微博正文 json 对象来做一个比较 通过对比工具 Beyond Compare 进行比较这两种情况下返回数据格式的不同可以看到 含图片的微博正文 返回数据比 含视频的微博正文多了 pic_infos 对象 继续向下比较可以看到 含图片的微博正文 比 含视频的微博正文 少了 page_info对象 而 page_info对象 里面的 media_info 对象正是视频所在对象 到这里对于微博正文列表内容 含图片微博正文 以及 含视频微博正文 的数据格式基本的分析及对比就结束了下面开始在 获取微博正文列表内容 DemoWeiBo 的 main 方法中补充这一块内容的获取。
补充图片 or 视频
下面开始补充图片 or 视频 链接的获取操作考虑到视频链接有 Expires 过期时间字段那么这里在导出 微博正文列表内容 到 Excel 中时保存 转存后的图片 or 视频路径首先给导出实体类 ExcelData 增加如下字段 然后在获取微博正文内容列表 main 方法中增加如下代码这里需要注意的是 pic_ids 和 pic_infos 是配套出现的 pic_ids 的值 就是 pic_infos 子对象的 key 关于 pic_infos 的子对象包括多种 宽高 尺寸的图片链接地址你可以根据自己的需要选择不同宽高的图片进行转存 最后补充的转存微博正文图片的代码如下 下面再来看获取视频操作你可以选择 media_info 对象内的以下几种清晰度的视频 或者也可以选择 media_info 对象内的 playback_list 里面是 四种清晰度的视频选择你可以选择其中一种或者多种清晰度的视频链接 最终补充获取微博正文视频内容的代码如下 到这里补充微博正文内容列表 获取 图片 or 视频的操作就完成了改造后的 DemoWeiBo.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.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;import java.io.BufferedInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.HttpURLConnection;
import java.net.URL;
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?uid1686546714feature0page%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数据列表ListExcelData excelDataList new ArrayList();// 循环抓取前2页数据for (int i 1; i 3; 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 JSON.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, );String repost data.getString(reposts_count);String comment data.getString(comments_count);String like data.getString(attitudes_count);//获取微博正文图片信息StringBuffer pic_url new StringBuffer();Long pic_num data.getLong(pic_num);if (pic_num 0 ) {JSONArray pic_ids data.getJSONArray(pic_ids);JSONObject pic_infos data.getJSONObject(pic_infos);// 遍历 pic_ids 获取 pic_infos 子对象 keyfor (Object json : pic_ids) {String key (String) json;JSONObject pic pic_infos.getJSONObject(key);JSONObject largest pic.getJSONObject(largest);// 提取图片URL并处理String imageUrl largest.getString(url);String filename imageUrl.substring(imageUrl.lastIndexOf(/) 1);// 下载图片String savePath E:\\2024weibo\\ filename;downloadPicture(imageUrl, savePath);pic_url pic_url.append(savePath).append(,);}}//获取微博正文视频信息String video_url ;JSONObject page_info data.getJSONObject(page_info);if (Objects.nonNull(page_info)) {JSONObject media_info page_info.getJSONObject(media_info);String mp4_hd_url media_info.getString(mp4_hd_url);String filename mp4_hd_url.substring(mp4_hd_url.lastIndexOf(/) 1, mp4_hd_url.indexOf(?));// 下载视频String savePath E:\\2024weibo\\ filename;downloadPicture(mp4_hd_url, savePath);video_url savePath;}//有一种情况就是当页面文本内容过多的时候微博默认不展示全部而是出现 【...展示】 按钮此时需要再请求一个 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);//图片地址excelData.setImgUrl(pic_url.toString());//视频地址excelData.setVideoUrl(video_url);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写入数据结束);}/*** 下载图片到指定路径** param imageUrl 图片的URL地址* param savePath 图片保存的本地路径*/public static void downloadPicture(String imageUrl, String savePath){BufferedInputStream in null;FileOutputStream out null;HttpURLConnection connection null;try {// 创建URL对象并打开连接URL url new URL(imageUrl);connection (HttpURLConnection) url.openConnection();// 设置请求方法为GETconnection.setRequestMethod(GET);// 建立连接connection.connect();// 获取响应码并判断是否下载成功int responseCode connection.getResponseCode();if (responseCode HttpURLConnection.HTTP_OK) {// 创建输入流和输出流用于读取和保存图片in new BufferedInputStream(connection.getInputStream());out new FileOutputStream(savePath);// 缓冲区用于一次读取和写入一定量的数据byte[] buffer new byte[1024];int bytesRead;// 循环读取直到没有数据while ((bytesRead in.read(buffer)) ! -1) {out.write(buffer, 0, bytesRead);}System.out.println(图片/视频 下载成功保存路径 savePath);} else {// 响应码不为HTTP_OK下载失败System.out.println(无法下载图片/视频响应码 responseCode);}}catch (Exception e) {// 捕获异常并打印堆栈信息e.printStackTrace();}finally {// 无论成功或失败最后都关闭流和连接// 关闭输入流if (in ! null) {try {in.close();} catch (IOException e) {// 将IO异常转为运行时异常抛出throw new RuntimeException(e);}}// 关闭输出流if (out ! null) {try {out.close();} catch (IOException e) {// 将IO异常转为运行时异常抛出throw new RuntimeException(e);}}// 关闭连接if (connection ! null) {connection.disconnect();}}}
}执行结果
执行main 方法后的输出 Excel 结果如图 图片链接和视频链接都已经转存记录成功。