大家好,我是雄雄,欢迎关注微信公众号:雄雄的小课堂
前言
整理新闻简报,不知不觉已经一年多了,从以前的手动整理,到现在的程序辅助整理,可所谓下了不少手段;
最早的时候,是别人给群里发,然后我复制到我自己的群里(因为大家都喜欢看),后来发现那个人不发了…就断了我的新闻简报之路了。
然后我就找了相关的新闻接口,也用了有一断时间,后来发现很不稳定,动不动就请求不返回了,或者返回的格式莫名的变,导致我这边处理不断地改,甚是苦恼,放弃。
于是就开始自己整理,每天去各大网站整理个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);
}
}