基于Java爬取微博数据(一) 微博主页正文列表数据

简介: 【5月更文挑战第16天】讲述如何通过 Java 爬取微博数据 微博主页正文列表数据,以及相应的注意点

爬虫背景

最近有这方面的需求,于是就研究了一下通过Java爬取微博数据,由于本人是后端Java开发,因此没有研究其他爬取微博数据的方法,比如通过Python爬取微博数据。大家感兴趣的可以自行查找基于Python爬取微博数据的方法。在爬取微博数据之前,先声明一下,本人爬取的微博数据仅用于测试Java爬取微博数据的可行性,并不会用于其他非正当地方,另外,爬取的数据也都是每个人都可以通过微博客户端正常看到的,不存在爬取隐秘数据的情况。大家在进行爬取数据的操作时也应注意不该爬取非授权数据,防止给自喜提“非法获取计算机信息系统数据罪”“破坏计算机信息系统罪”等。一切爬虫操作都应在合法合规的情况下进行。

爬虫分析

在进行爬虫操作之前,我们先来看一下微博客户端的页面结构,以及对应的请求链接,数据响应情况等,方便为后续爬取微博数据做准备。比如这里打开一个环球网的微博主页:https://weibo.com/u/1686546714  可以看到

那么我们打开浏览器开发者工具,按F12键,打开开发者工具,选择【网络】或者【network】,然后再次刷新当前页面可以看到如下请求


点击对应的URL,查看URL的响应,最终会找到请求链接 /ajax/statuses/mymblog?uid=1686546714&page=1&feature=0  的响应正是我们需要爬取的数据内容来源



到这里,确定了数据来源URL之后,我们就可以进行后续的爬取数据操作了。

爬取数据

整个爬取数据操作我们需要用到两个 jar 包 hutool-all 、 fastjson ,那么我们需要首先在项目 pom.xml 文件中引入这两个 jar 包

<!-- hutool-all -->
<dependency>
  <groupId>cn.hutool</groupId>
  <artifactId>hutool-all</artifactId>
  <version> 5.3.4</version>
</dependency>
<!-- 阿里JSON解析器 -->
<dependency>
  <groupId>com.alibaba</groupId>
  <artifactId>fastjson</artifactId>
  <version>1.2.80</version>
</dependency>

jar 包引入之后开始编写代码,编写完成后完整代码如下  DemoWeiBo.java

package com.ruoyi.web.controller.demo.controller;

import cn.hutool.http.HttpResponse;
import cn.hutool.http.HttpUtil;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
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";

        // 初始化日期格式
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

        // 循环抓取3页数据
        for (int i = 1; i <= 1; 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 jsonObject2 = JSONObject.parseObject(body).getJSONObject("data");
                JSONArray list = null;
                if (Objects.nonNull(jsonObject2)) {
                    // 处理数据列表
                    list = jsonObject2.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);
                    }
                }

                // 输出完成提示并关闭响应,休眠以避免频繁请求
                System.out.println("第" + i + "页数据获取完毕");
                response.close();
                // 如果列表为空,终止循环
                if (list == null || list.size() == 0) {
                    break;
                }
                Thread.sleep(700);
            } catch (Exception e) {
                // 打印异常信息
                e.printStackTrace();
            }
        }
    }
}

代码中请求 URL 中的参数 page 代表当前爬取的是第几页数据,因此代码中进行了字符占位,方便后续的分页数据的替换


爬取微博数据时,必须要为请求 URL 添加 Header 信息 ,增加请求头 Cookie ,没有请求头 Cookie 的话,无法返回正常的响应数据,而是重定向到登录链接地址



那么关于请求头 Cookie 的来源,我们可以到浏览器的【网络】中刚才找到的请求 URL ,点击【标头】 下滑看到如下内容,红框部分就是 Cookie 内容


由于没有登录账号,因此这里的 Cookie 就属于访客 Cookie,那么微博对于访客 Cookie 的数据访问权限比较有限,在通过访客 Cookie 获取数据时,你只能获取当前请求 URL 的前两页数据,每页 20 条,整体也就是 40条数据,如果有置顶微博的话,置顶微博不算在这两页内,那么你就可能会获取到 大于 40 条的微博数据。当你获取 第 3 页数据时,请求链接只返回成功状态,但是没有 data 数据返回


而正常情况下 response.body() 应该返回这样的内容


response.body() 数据格式化之后 如图



获取到微博数据之后,在代码中打印的数据内容具体属性 text : 文本内容  reposts_count : 转发数  comments_count : 评论数  attitudes_count : 点赞数

最终的打印结果可以看到如下请求链接返回内容,


到这里我们爬取微博数据就完成了,整个代码逻辑比较清晰,后续对于爬取到的微博数据的处理可以根据具体的业务需求。


另外,对于代码中的正则表达式 String regex = "<[^<>]*>"; 表示的意义:【用于匹配以"<"开头,紧接着是0个或多个不包括"<"和">"的字符,最后以">"结尾的字符串。这个正则表达式常用于从一段文本中提取标签内容,例如从

<html><body><h1>Hello, World!</h1></body></html>

中提取出

Hello, World!

在线正则表达式匹配结果如图


当然,微博数据并不是只有这些的,你可以直接将我们爬取数据的请求 URL 放在浏览器看到


注意点

对于请求 URL 请求头 Cookie 的获取,你可以选择游客 Cookie 或者登录账号后的 Cookie ,这里个人建议使用登录账号后从浏览器拿出的 Cookie,可以获取当前登录账号关注过的用户发布的所有微博数据。关于有效期,百度搜索关于微博登录账号后的 Cookie 有效期是 30天,个人实测了一次,大概十几天后失效,由于中途可能会有其他影响,不一定准确。有时间的大家也可以测一下。不建议使用游客 Cookie 的原因除了获取数据只能获取前 2 页数据外的因素,还有就是不知道具体游客 Cookie 的有效期,有不确定因素在里面,无法保证数据来源稳定了。


到这里可能有人会觉得从浏览器拿出登录后的 Cookie 操作显得不太高级,且比较笨拙,想要通过代码模拟微博登录从而获取 Cookie,这里个人给出的建议是微博目前的登录逻辑安全性较高,需要短信验证且有动态图验证,即使通过扫码登录或者账号登录,验证同样也是多重验证,且不说模拟登录的难度有多大,如果你能成功绕过登录或者模拟登录成功,那么感觉你离“破坏计算机信息系统罪”也不远了。因此个人建议保守一点,手动登录后从浏览器拿出 Cookie 放入爬虫代码中进行数据获取即可,无需费力不讨好的模拟登录。


另外说明,本文是把原有的   基于Java爬取微博数据(一) 微博主页正文列表数据  拿过来,而原有的博文将会更名为 基于Java爬取微博数据(完整版),特此说明。

相关文章
|
2月前
|
Java API 开发工具
【Azure Developer】Java代码实现获取Azure 资源的指标数据却报错 "invalid time interval input"
在使用 Java 调用虚拟机 API 获取指标数据时,因本地时区设置非 UTC,导致时间格式解析错误。解决方法是在代码中手动指定时区为 UTC,使用 `ZoneOffset.ofHours(0)` 并结合 `withOffsetSameInstant` 方法进行时区转换,从而避免因时区差异引发的时间格式问题。
205 3
|
2月前
|
算法 Java
Java多线程编程:实现线程间数据共享机制
以上就是Java中几种主要处理多线程序列化资源以及协调各自独立运行但需相互配合以完成任务threads 的技术手段与策略。正确应用上述技术将大大增强你程序稳定性与效率同时也降低bug出现率因此深刻理解每项技术背后理论至关重要.
226 16
|
3月前
|
数据采集 JSON Java
Java爬虫获取1688店铺所有商品接口数据实战指南
本文介绍如何使用Java爬虫技术高效获取1688店铺商品信息,涵盖环境搭建、API调用、签名生成及数据抓取全流程,并附完整代码示例,助力市场分析与选品决策。
|
3月前
|
数据采集 存储 前端开发
Java爬虫性能优化:多线程抓取JSP动态数据实践
Java爬虫性能优化:多线程抓取JSP动态数据实践
|
传感器 分布式计算 安全
Java 大视界 -- Java 大数据在智能安防入侵检测系统中的多源数据融合与分析技术(171)
本文围绕 Java 大数据在智能安防入侵检测系统中的应用展开,剖析系统现状与挑战,阐释多源数据融合及分析技术,结合案例与代码给出实操方案,提升入侵检测效能。
|
1月前
|
JSON 网络协议 安全
【Java】(10)进程与线程的关系、Tread类;讲解基本线程安全、网络编程内容;JSON序列化与反序列化
几乎所有的操作系统都支持进程的概念,进程是处于运行过程中的程序,并且具有一定的独立功能,进程是系统进行资源分配和调度的一个独立单位一般而言,进程包含如下三个特征。独立性动态性并发性。
153 1
|
1月前
|
JSON 网络协议 安全
【Java基础】(1)进程与线程的关系、Tread类;讲解基本线程安全、网络编程内容;JSON序列化与反序列化
几乎所有的操作系统都支持进程的概念,进程是处于运行过程中的程序,并且具有一定的独立功能,进程是系统进行资源分配和调度的一个独立单位一般而言,进程包含如下三个特征。独立性动态性并发性。
168 1
|
2月前
|
数据采集 存储 弹性计算
高并发Java爬虫的瓶颈分析与动态线程优化方案
高并发Java爬虫的瓶颈分析与动态线程优化方案
Java 数据库 Spring
142 0
|
3月前
|
缓存 并行计算 安全
关于Java多线程详解
本文深入讲解Java多线程编程,涵盖基础概念、线程创建与管理、同步机制、并发工具类、线程池、线程安全集合、实战案例及常见问题解决方案,助你掌握高性能并发编程技巧,应对多线程开发中的挑战。