爬取某个公众号下所有文章的方法

363 阅读1分钟

仅做下记录,以下代码所做的事情是抓取了某个公众号下的所有文章,然后以时间正序做了排序,处理为markdown的超链接格式,方便分享。 参考文章:用Python爬取指定公众号所有文章 - 知乎 (zhihu.com) 代码如下:

package com.belizer;


import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.http.HttpRequest;
import cn.hutool.http.HttpResponse;
import cn.hutool.http.HttpUtil;
import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import java.nio.charset.StandardCharsets;
import java.text.MessageFormat;
import java.util.*;
import java.util.concurrent.TimeUnit;

public class Main {
    /**
     * 某个公众号的所有文章抓取与处理,
     * 此处处理为markdown的超链接格式,方便分享。
     * 调整公众号文章的顺序为正序,
     * 爬取某个公众号所有文章的方式参考的文章为:
     * <a href="https://zhuanlan.zhihu.com/p/379062852">...</a>
     *
     */
    public static void main(String[] args) {
        // 创建文章列表,初始化数量的依据是要抓取的文章数量
        List<Map<String,Object>> articleList = new ArrayList<>(609);
        // 分页页码数,依据要抓取的文章数量计算
        int pageCount = 122;
        // markdown格式文章链接模板
        String aTag = "[{0}]({1} \"{2}\")\r\n";

        String url = "https://mp.weixin.qq.com/cgi-bin/appmsg";
        // Cookie
        String cookie = "";
        // User-agent
        String userAgent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/115.0.0.0 Safari/537.36 Edg/115.0.1901.203";
        // 公众号id
        String fakeId = "1000000000";
        // token
        String token = "1234567890";

        for (int i = 0; i <= (pageCount - 1); i++) {
            int begin = i * 5;

            try {
                TimeUnit.SECONDS.sleep(new Random().nextInt(10));
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }


            HttpRequest get = HttpUtil.createGet(url);
            get.header("Cookie",cookie);
            get.header("User-agent",userAgent);

            get.body("action=list_ex&begin="+begin+"&count=5&fakeid="+fakeId+"&type=9&query=&token="+token+"&lang=zh_CN&f=json&ajax=1");

            HttpResponse response = get.execute();

            String body = response.charset(StandardCharsets.UTF_8).body();
            System.out.println("response:" + body);

            JSONObject body_json = JSONUtil.parseObj(body);

            JSONObject baseResp = (JSONObject)body_json.get("base_resp");
            if (Objects.nonNull(baseResp)) {
                if (Objects.nonNull(baseResp.get("ret")) && baseResp.get("ret").equals(0)) {
                    JSONArray appMsgList = (JSONArray) body_json.get("app_msg_list");
                    if (!appMsgList.isEmpty()) {
                        Iterator<Object> iterator = appMsgList.stream().iterator();
                        while (iterator.hasNext()) {
                            JSONObject jsonObject = (JSONObject) iterator.next();
                            if (Objects.nonNull(jsonObject)) {
                                Map<String, Object> article = new HashMap<>();
                                article.put("title", jsonObject.get("title"));
                                article.put("link", jsonObject.get("link"));
                                article.put("update_time", jsonObject.get("update_time"));

                                articleList.add(article);
                            }
                        }

                    }
                } else if(Objects.nonNull(baseResp.get("ret")) && baseResp.get("ret").equals(200013)){
                    // 被微信流量控制,等待1个小时,再执行
                    try {
                        TimeUnit.HOURS.sleep(1);
                    } catch (InterruptedException e) {
                        throw new RuntimeException(e);
                    }
                    continue;
                }else {
                    //获取不到数据终止循环
                    break;
                }
            }


        }

        if (CollectionUtil.isNotEmpty(articleList)) {
            articleList.sort((a1,a2)->{
                long updateTime1 = Long.parseLong(a1.get("update_time")+"");
                long updateTime2 = Long.parseLong(a2.get("update_time")+"");

                Date date1 = new Date(updateTime1);
                Date date2 = new Date(updateTime2);
                return date1.compareTo(date2);
            });

            articleList.forEach(article->{
                String content = MessageFormat.format(aTag,article.get("title"),article.get("link"),article.get("title"));
                System.out.println(content);
            });
        }



    }



}

使用的依赖

<dependency>
    <groupId>cn.hutool</groupId>
    <artifactId>hutool-all</artifactId>
    <version>5.8.21</version>
</dependency>

需要注意的问题,如微信的流量控制等参考文章均已提到,使用前建议仔细阅读参考文章。 另外,本文章只做技术分享,您使用本文章所用到的技术做的任何事情与本文章以及本文作者无关。