Java爬虫Java Jsoup爬取csdn等级、排名、访问量、原力等级、个人成就

写在前面

csdn创作数据最多只能查看近一个月的数据(访问量、排名、粉丝数、原力等级、积分、点赞数、收藏数、积分等信息),如果想查看以前的,只能自己保存记录了。

咱们干技术的,总不可能自己天天手动记录,必须是使用程序自动记录每天的数据变化情况,可以使用Java爬虫Jsoup爬取个人博客数据进行记录。记录数据后,时不时查出来看一看,充值一下写博客的动力。

Jsoup简介

Jsoup 是一款 Java 的 HTML 解析器,可直接解析某个 URL 地址,通过请求 URL 地址获取 HTML 文本内容。提供了一套非常省力的API,可通过DOM,CSS 以及类似于 jQuery 的操作方法(类、元素、属性等选择器)来取出和操作数据。

Jsoup依赖 pom.xml

        <dependency>
            <groupId>org.jsoup</groupId>
            <artifactId>jsoup</artifactId>
            <version>1.15.3</version>
        </dependency>

csdn 博客统计数据

csdn 博客主页主要分为 4 部分统计数据:

  • 整体统计:访问量、排名、粉丝;
  • 原力等级:当前等级、总分;
  • 个人成就:点赞、评论、收藏;
  • 文章列表:各文章的点赞、阅读、评论、收藏。

下面针对这四种主要统计进行爬取解析。

Jsoup爬取csdn博客原创、排名、粉丝、铁粉

总体统计数据使用 class 选择器,user-profile-statistics-num,博客首页按 F12,选择 Elements,搜索 user-profile-statistics-num 选择器,相关js就是整体统计数据部分。

在这里插入图片描述
解析dom代码,通过获取 user-profile-statistics-num 选择器对应的值,就是原创、排名、粉丝、铁粉相关数据。

    private static void parseProfiles(Elements elementsProfile) {
        for (Element ele : elementsProfile) {
            if (ele.parent() == null) {
                continue;
            }
            List<Node> nodes = ele.parent().childNodes();
            for (Node node : nodes) {
                Attributes attributes1 = node.attributes();
                List<Attribute> list = attributes1.asList();
                for (Attribute attr : list) {
                    if ("user-profile-statistics-num".equals(attr.getValue())) {
                        TextNode nodeNum = (TextNode) node.childNode(0);
                        // 123
                        System.out.println("num: " + nodeNum.text());
                    } else if ("user-profile-statistics-name".equals(attr.getValue())) {
                        TextNode nodeName = (TextNode) node.childNode(0);
                        // 总访问量
                        System.out.println("name: " + nodeName.text());
                    }
                }
            }
        }
    }

Jsoup爬取csdn博客原力等级

原力等级使用 class 选择器,博客首页按 F12,选择 Elements,搜索 influence-left 选择器,相关js就是原力等级相关统计。
在这里插入图片描述

解析dom代码,通过获取 user-profile-statistics-num 选择器对应的值,就是原力等级、总分、当月分等相关数据。

    private static void parseInfluences(Elements elementsInfluence) {
        for (Element ele : elementsInfluence) {
            // influence-left
            List<Node> nodes = ele.childNodes();
            for (Node node : nodes) {
                // dl
                List<Node> nodesDls = node.childNodes();
                // 0 dl 等级,1 dl 总分, 2 a child dl 当月
                for (Node nodeDl : nodesDls) {
                    // dd k(等级), dt v(1)
                    if (nodeDl instanceof Element eleDl) {
                        String tagName = eleDl.tagName();
                        if ("dl".equals(tagName)) {
                            List<Node> nodesDdDt = nodeDl.childNodes();
                            handleInfluenceDdDt(nodesDdDt);
                        } else if ("a".equals(tagName)) {
                            List<Node> nodesDdDt = eleDl.childNodes().getFirst().childNodes();
                            handleInfluenceDdDt(nodesDdDt);
                        }
                    }
                }
            }
        }
    }

Jsoup爬取csdn博客个人成就点赞、评论、收藏

原力等级使用 class 选择器,博客首页按 F12,选择 Elements,搜索 aside-common-box-achievement 选择器,相关js就是个人成就相关统计。
在这里插入图片描述

解析dom代码,通过获取 aside-common-box-achievement 选择器对应的值,就是点赞、评论、收藏、代码复制等相关数据。


    private static void parseAchievements(Elements elementsAchievement) {
        for (Element ele : elementsAchievement) {
            // li
            List<Node> nodesLi = ele.childNodes();
            for (Node li : nodesLi) {
                List<Node> nodesDiv = li.childNodes();
                for (Node div : nodesDiv) {
                    if (div instanceof Element eleDiv) {
                        if ("div".equals(eleDiv.tagName())) {
                            List<Node> nodes = eleDiv.childNodes();
                            for (Node span : nodes) {
                                if (span instanceof Element eleSpan) {
                                    if ("em".equals(eleSpan.tagName())) {
                                        List<Node> ems = eleSpan.childNodes();
                                        Attributes attributes1 = eleSpan.attributes();
                                        List<Attribute> list = attributes1.asList();
                                        for (Attribute attr : list) {
                                            if ("title".equals(attr.getKey())) {
                                                System.out.println("title: " + attr.getValue());
                                            }
                                        }
                                        for (Node nodeEm : ems) {
                                            if (nodeEm instanceof Element eleSpan1) {
                                                TextNode textNode = (TextNode) eleSpan1.childNodes().getFirst();
                                                System.out.println("num: " + textNode.text());
                                            } else if (nodeEm instanceof TextNode textNode) {
                                                System.out.println("name: " + textNode.text());
                                            }
                                        }
                                        TextNode textNode = (TextNode) eleSpan.childNodes().getFirst();
                                        System.out.println("num: " + textNode.text());
                                    } else {
                                        TextNode textNode = (TextNode) eleSpan.childNodes().getFirst();
                                        System.out.println("num: " + textNode.text());
                                    }
                                } else if (span instanceof TextNode textNode) {
                                    System.out.println("name: " + textNode.text());
                                }
                            }
                        }
                    }
                }
            }
        }
    }

Jsoup爬取csdn博客文章列表阅读、点赞、评论、收藏

原力等级使用 标签 选择器,博客首页按 F12,选择 Elements,搜索 article 选择器,相关js就是博客文章列表相关统计。
在这里插入图片描述

解析dom代码,通过获取 article 选择器对应的值,就是阅读、点赞、评论、收藏等相关数据。

   private static void parseArticles(Elements articles) {
        for (Element art : articles) {
            Elements artItem = art.select(".blog-list-box-top");
            List<Node> nodes = artItem.getFirst().childNodes();
            if (!nodes.isEmpty()) {
                Node node = nodes.getFirst();
                if (node instanceof Element h4) {
                    System.out.println("标题:" + h4.text());
                }
            }
            Elements views = art.select(".view-num");
            if (!views.isEmpty()) {
                Element view = views.getFirst();
                if ("span".equals(view.tagName())) {
                    Node first = view.childNodes().getFirst();
                    if (first instanceof TextNode tf) {
                        System.out.println("阅读:" + tf.text());
                    }
                }
            }
            Elements likes = art.select(".give-like-num");
            if (!likes.isEmpty()) {
                Element like = likes.getFirst();
                if ("span".equals(like.tagName())) {
                    Node first = like.childNodes().getFirst();
                    if (first instanceof TextNode tl) {
                        System.out.println("点赞:" + tl.text());
                    }
                }
            }
            Elements comments = art.select(".comment-num");
            if (comments.size() > 1) {
                Element comment = comments.get(0);
                if ("span".equals(comment.tagName())) {
                    Node first = comment.childNodes().getFirst();
                    if (first instanceof TextNode tf) {
                        System.out.println("评论:" + tf.text());
                    }
                }
                Element comment1 = comments.get(1);
                if ("span".equals(comment1.tagName())) {
                    Node first1 = comment.childNodes().getFirst();
                    if (first1 instanceof TextNode tf) {
                        System.out.println("收藏:" + tf.text());
                    }
                }
            }
        }
    }

程序入口

   public static void main(String[] args) throws IOException {

        // 替换为需要爬的博客首页
        String indexUrl = "https://blog.csdn.net/zs";

        // 访问博客首页
        Document document = Jsoup.connect(indexUrl).get();

        // 总访问量、原创、排名、粉丝、铁粉
        Elements elementsProfile = document.select(".user-profile-statistics-num");
        parseProfiles(elementsProfile);

        // 当前等级、当前总分、当月
        Elements elementsInfluence = document.select(".influence-bottom");
        parseInfluences(elementsInfluence);

        // 点赞、评论、收藏、积分
        Elements elementsAchievement = document.select(".aside-common-box-achievement");
        parseAchievements(elementsAchievement);

        // 博客列表每篇 阅读、点赞、评论、收藏
        Elements articles = document.getElementsByTag("article");
        parseArticles(articles);
    }

总结

通过上面的代码,可以使用Java爬虫jsoup轻松爬到csdn相关统计数据。
爬虫虽好,可不要乱用哦!一天请求一次即可,不要疯狂刷新哈。。。

爬到的数据记录到本地,时不时查询总结一番,你也来试试吧~

  • 18
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值