新闻简报背后的技术剖析

大家好,我是雄雄,欢迎关注微信公众号:雄雄的小课堂

前言

整理新闻简报,不知不觉已经一年多了,从以前的手动整理,到现在的程序辅助整理,可所谓下了不少手段;

最早的时候,是别人给群里发,然后我复制到我自己的群里(因为大家都喜欢看),后来发现那个人不发了…就断了我的新闻简报之路了。

然后我就找了相关的新闻接口,也用了有一断时间,后来发现很不稳定,动不动就请求不返回了,或者返回的格式莫名的变,导致我这边处理不断地改,甚是苦恼,放弃。

于是就开始自己整理,每天去各大网站整理个10条左右,收到发送到群里,这样有个问题就是,新闻虽然稳定了,但是我经常会忘,而且周末想睡个懒觉,发的就晚,但是看简报的人不睡懒觉,催着我发…于是这个时候就自己琢磨研究了下机器人,把发简报改成自动化,但是整理还是手动的。

自动化获取高质量新闻源

曾经多次,将获取新闻源也改成自动的,毕竟能减少点工作量,同一件事坚持一年以上,期间往往会有各种各样的突发情况,比如在外地出差,或者晚上陪客户吃饭,可能就会影响整理(因为所有内容都是提前一天晚上整理好,放在缓存里面,第二天一早定时发送到群中)。

找了好多种方法,比如采集、调用接口,但是结果很不理想,不是质量不行,就是不稳定,本着靠被人不如靠自己的原则,还是手动整理吧,这样质量能保证,但是解放不了双手。

这两天,发现了个rss的订阅源,蛮符合我的要求,于是又用java写成了自动化了…

下面放一下主要的代码段:


    /**
     * 新闻,然后生成文件
     * @return
     */
    @GetMapping("/crawlNewsRegularly")
    @Scheduled(cron = " 0 10 22 * * ?")
    public ResponseResult crawlNewsRegularly() {
        Callable<JSONArray> task1 = this::readXmlByChina;
        Callable<JSONArray> task2 = this::readXmlByWorld;
        try {
            // 国内新闻
            Future<JSONArray> chinaNewsFuture = executorService.submit(task1);
            JSONArray chinaNews = chinaNewsFuture.get();
            Future<JSONArray> worldNewsFuture = executorService.submit(task2);
            // 国际新闻
            JSONArray worldNews = worldNewsFuture.get();
            LocalDate today = LocalDate.now();
            try (BufferedWriter writer = new BufferedWriter(
                    new OutputStreamWriter(
                            //log文件可以解决乱码问题
                            Files.newOutputStream(Paths.get(filePath + "DailyNews_" + today + ".log")),
                            StandardCharsets.UTF_8
                    ))
            ) {
                //语音生成的模版
                generateVoiceTemplate(chinaNews, worldNews, writer);
                //公众号模版
                generateWechatTemplate(chinaNews, worldNews, writer);
                //将新闻信息放在缓存中,方便给群里瑞松
                setRedisByNews(chinaNews, worldNews);
            } catch (Exception e) {
                log.error("保存爬取的新闻时出错!", e);
            }
        } catch (InterruptedException | ExecutionException e) {
            log.error("处理Future结果时出错!", e);
            // 重新设置中断状态,如果是在中断状态下被调用的
            Thread.currentThread().interrupt();
        } catch (Exception e) {
            log.error("未知错误!", e);
        }
        log.info("执行了定制爬取《联合报》的新闻,保存在文件中");
        return ResponseResult.success();
    }

按照格式生成语音的模版


 /**
     * 按照格式生成语音的模版
     * @return
     */
    public void generateVoiceTemplate( JSONArray chinaNews, JSONArray worldNews,BufferedWriter writer) throws IOException, ParseException {
        StringBuilder sb = new StringBuilder("每天三分钟,朝闻天下事。");
        List<LifeTip> lifeTip = lifeTipService.getLifeTipRangeOne("早安语录", 1);
        String zaoan = lifeTip.get(0).getContent();
        sb.append(zaoan);
        //开始获取日期,后面参数是1表示增加一天,也就是明天
        LocalDate tomorrow = LocalDate.now().plusDays(1);
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy年MM月dd日");
        //格式化后的明天日期
        String formattedDateStr = tomorrow.format(formatter);
        //周几
        String week = DateUtils.getDaysByWeekChina(tomorrow.toString());
        //开始获取农历
        Calendar today = Calendar.getInstance();
        today.add(Calendar.DATE, 1);
        DateUtils lunar = new DateUtils(today);
        String nongli = lunar.toString().substring(lunar.toString().indexOf("年") + 1);
        sb.append("今天是").append(formattedDateStr).append(",星期").append(week).append(",农历").append(nongli).append(",祝工作愉快,身体健康,生活喜乐。");
        writer.newLine();
        sb.append("首先我们来关注一下国内新闻:");
        // 遍历item数组并获取每个item的title
        for (int i = 0; i < chinaNews.size(); i++) {
            JSONObject item = chinaNews.getJSONObject(i);
            String title = item.getStr("title");
            // 写入文件
            if (i == 0) {
                //将头部信息写入到文件中
                writer.write(sb.toString());
                writer.newLine();
            }
            writer.write(i + 1 + ". " + title + "。");
            writer.newLine();

            // 循环结束最后写入空行
            if (i == chinaNews.size() - 1) {
                writer.newLine();
            }
        }
        //遍历国际新闻
        for (int i = 0; i < worldNews.size(); i++) {
            JSONObject item = worldNews.getJSONObject(i);
            String title = item.getStr("title");
            // 写入文件
            if (i == 0) {
                writer.write("接下来是国际新闻:");
                writer.newLine();
            }
            writer.write(i + 1 + ". " + title + "。");
            writer.newLine();
        }
        writer.write("今日新闻简报就到这里,欢迎关注微信公众号:雄雄的小课堂,每天早上准时为您播报!您也可以通过微信听书搜索:雄雄的小课堂 找到我哦!");
    }

按照格式生成公众号模板新闻

/**
     * 按照格式生成公众号模板新闻
     * @return
     */
    public void generateWechatTemplate(JSONArray chinaNews, JSONArray worldNews, BufferedWriter writer) throws IOException {
        writer.newLine();
        writer.newLine();
        writer.write("******************************************************************************");
        writer.newLine();
        writer.newLine();
        //国内新闻
        // 遍历item数组并获取每个item的title
        for (int i = 0; i < chinaNews.size(); i++) {
            JSONObject item = chinaNews.getJSONObject(i);
            String title = item.getStr("title");
            // 写入文件
            if (i == 0) {
                writer.write("## 🤖国内新闻");
                writer.newLine();
            }
            writer.write(i + 1 + "." + title + "。");
            writer.newLine();
            writer.newLine();

            // 循环结束最后写入空行
            if (i == chinaNews.size() - 1) {
                writer.newLine();
            }
        }

        //遍历国际新闻
        for (int i = 0; i < worldNews.size(); i++) {
            JSONObject item = worldNews.getJSONObject(i);
            String title = item.getStr("title");
            // 写入文件
            if (i == 0) {
                writer.write("## 🐸国际新闻");
                writer.newLine();
            }
            writer.write(i + 1 + "." + title + "。");
            writer.newLine();
            writer.newLine();
        }
        writer.newLine();
        List<LifeTip> lifeTip = lifeTipService.getLifeTipRangeOne("早安语录", 1);
        String zaoan = lifeTip.get(0).getContent();
        writer.write("【微语】:" + zaoan);
        writer.newLine();
        writer.newLine();
        writer.newLine();
        writer.write("**以上新闻来源:互联网搜集整理**");
    }

将国内新闻和国际新闻都放在redis缓存中,主要用于发送到微信群中,以及提供给别人调用。

/**
     * 将国内新闻和国际新闻都放在redis缓存中
     * @return
     */
    private void setRedisByNews(JSONArray chinaNews, JSONArray worldNews){
        JSONArray  arrayGuoNei = new JSONArray();
        JSONArray arrayGuoJi = new JSONArray();
        for (int i = 0; i < 10; i++) {
            JSONObject itemChina = chinaNews.getJSONObject(i);
            JSONObject itemWord = worldNews.getJSONObject(i);
            String titleChina = itemChina.getStr("title");
            arrayGuoNei.add(titleChina);
            String titleWord = itemWord.getStr("title");
            arrayGuoJi.add(titleWord);
        }
        //将内容放在缓存中
        redisService.setCacheObject("penpaiReBang", arrayGuoNei);
        redisService.setCacheObject("reBangGuoJiNews", arrayGuoJi);
    }

下面是两个处理xml的公共方法:

    private JSONArray readXmlByChina() {
        try {
            // 读取XML文件内容
            URL url = new URL(crawlNewsUrl_china);
            BufferedReader in = new BufferedReader(new InputStreamReader(url.openStream()));
            StringBuilder xmlContent = new StringBuilder();
            String inputLine;
            while ((inputLine = in.readLine()) != null) {
                xmlContent.append(inputLine);
            }
            in.close();

            // 将XML转换为JSON
            String xmlString = xmlContent.toString();
            JSONObject jsonObj = XML.toJSONObject(xmlString);
            // 获取channel中的item数组
            return jsonObj.getJSONObject("rss")
                    .getJSONObject("channel")
                    .getJSONArray("item");
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    private JSONArray readXmlByWorld() {
        try {
            // 读取XML文件内容
            URL url = new URL(crawlNewsUrl_world);
            BufferedReader in = new BufferedReader(new InputStreamReader(url.openStream()));
            StringBuilder xmlContent = new StringBuilder();
            String inputLine;
            while ((inputLine = in.readLine()) != null) {
                xmlContent.append(inputLine);
            }
            in.close();

            // 将XML转换为JSON
            String xmlString = xmlContent.toString();
            JSONObject jsonObj = XML.toJSONObject(xmlString);
            // 获取channel中的item数组
            return jsonObj.getJSONObject("rss")
                    .getJSONObject("channel")
                    .getJSONArray("item");
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

  • 3
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

穆雄雄

哎,貌似还没开张来着呢~

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值