zoukankan      html  css  js  c++  java
  • 如何给你爱的读者每天发早报?

    早报

    最近和一个朋友唠嗑,听她吐槽了好久……

    她是一个社群运营,每天早上收集信息、整理、排版、到推送社群,大概要花费30分钟,需要花费大量的时间和精力,苦不堪言。

    那么有没有办法将这个流程自动化呢?于是乎,我们想到了 「 除了生孩子无所不能的 Python 」,请接着看!

    640?wx_fmt=png

                 早报图片

    思路很简单,分为3步:

    1.从目标网站采集信息;

    2.将采集到的信息生成早报图片

    3.将生成的图片发送到微信群或好友

    640?wx_fmt=png

                     实现流程

    一、早报数据收集

    网络上有很多提供早报的网站,这里为了避免做广告,但是为了演示方便,只提供地址,不说明名字,下文将我采集的网站称为A网站,A网站有专门的早报模块。

    640?wx_fmt=png

                       A网站

    1.获取最新日报的url

    首先获取A网站最新早报页面的链接,通过查看网页源代码发现,所有的展示信息在页面 li 中,我们要获取的链接的地址正好在h2中,所以分析完毕开始提取链接。

    640?wx_fmt=png

    首先引入相关的网络请求库requests,如下图:

    1 import requests    
    2 from bs4 import BeautifulSoup

    点击第一个早报信息进入后链接为https://www.pmtown.com/archives/197318.html,而我们使用find方式找到最新日报页面的链接为相对路径/archives/197318.html,所以需要我们手动组装完整的URL,具体见下方。

    1 # 获取第一个早报的url    
    2 obj1 = requests.get('http://www.pmtown.com/archives/category/早报')    
    3 url_obj = BeautifulSoup(obj1.text, 'lxml')    
    4 url = url_obj.find('h2').find('a').get('href')    
    5 first_url = 'http://www.pmtown.com' + url

    2.获取日报页面的日报内容

    640?wx_fmt=png

    制作早报时,我们只需要新闻的标题即可,通过分析发现页面比较简单,所有的标题都在p下面,所以我们直接提取内容

     1 # 获取当前页    
     2 obj = requests.get(first_url)    
     3 obj_1 = BeautifulSoup(obj.text, 'lxml')    
     4 titles = obj_1.findAll('p')    
     5  
     6     
     7 # 获得新闻标题    
     8 a = []    
     9 for title in titles:    
    10     a.append(title.get_text())

    获取的内容部分截图如下

    640?wx_fmt=png

                             内容截图

    3.文本处理

    A网站日报的内容有科技头条,国内动态,海外动态和投资收购四个模块,实质得到的文本除了“科技头条”得到的日报标题是列表,

    而其他3个模块的日报标题各自在一整段字符串中,所以就要对字符串进行处理,使其成为列表。

    640?wx_fmt=png

    定义函数,将国内动态,海外动态和投资收购的日报标题分割开来,组成新的列表,这样日报的4类内容的格式就统一了

    1 # 将新闻文本格式统一,生成新的列表    
    2 def get_text(text_orgin):    
    3     #将标题的序号统一替换为‘sp’,然后将整段文本分割组成新的日报标题列表    
    4     first_list = re.sub(r'd{1,2}、', 'SP', text_orgin)    
    5     mid_list = first_list.split('SP')    
    6     finnal_list = mid_list[1:len(mid_list)]    
    7     return finnal_list

    上述步骤中,我们把标题的序号替换了,所以需要需要加上新的序号,具体操作

    1 # 定义函数,给信息加上编号,输出列表    
    2 def inf_list(inf_orgin):    
    3     inf_after = []    
    4     for num, single_info in enumerate(inf_orgin):    
    5         inf_after.append(u'%s、%s' % ((num + 1), single_info))    
    6     return inf_after

    二、生成早报图片

    首先导入画图的库,这里使用PIL库

    
    

    1.画日报报头

    设置字体类型和颜色,字体类型后续会用到,字体需要填写自己电脑上有的字体,window一般在C:/Windows/Fonts文件夹下,如果字体设置错误,程序会报错。

    1 # 设置字体样式    
    2 font_type = 'C:/Windows/Fonts/simkai.ttf'    
    3 font_medium_type = 'C:/Windows/Fonts/simkai.ttf'    
    4 header_font = ImageFont.truetype(font_medium_type, 55)    
    5 title_font = ImageFont.truetype(font_medium_type, 20)    
    6 font = ImageFont.truetype(font_type, 38)    
    7 color = "#726053"    
    8 color1 = "#294E76"

    (1)画题目

    header_x 和header_y是要画图的坐标,color是题目的颜色,header_font是题目的字体类型。

    1 # 开始画图    
    2 header = '互联网日报'    
    3 header_x = 130    
    4 header_y = 200    
    5 draw.text((header_x, header_y), u'%s' % header, color, header_font)

    (2)画副标题

    1 title = '由python脚本自动生成'    
    2 title_x = header_x    
    3 title_y = header_y + 80    
    4 draw.text((title_x, title_y), u'%s' % title, color1, title_font)

    (3)添加当前时间

    在图片上添加生成图片的时间,单纯是为了显得高大上。首先引入import time模块,然后开始画图

    1 cur_time = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())    
    2 cur_time_x = 666    
    3 cur_time_y = title_y    
    4 cur_time_font = ImageFont.truetype(font_type, 20)    
    5 draw.text((cur_time_x, cur_time_y), u'%s' %cur_time, color, cur_time_font)

    报头效果预览

    640?wx_fmt=png

    2.画日报内容

    因为新闻标题很长(最多2行),而图片是有宽度上限的,所以必须考虑换行的问题,我的处理方式是将原列表直接按照设定的宽度(我设定为750px)处理成为新列表,具体操作见下。

     1 def old_to_new_list(oldlist):    
     2     newlist = []    
     3     for single_text in oldlist:    
     4         if font.getsize(single_text.strip())[0] < 750 or font.getsi(single_text.strip()) == 750:    
     5             newlist.append(single_text)    
     6         else:    
     7             strList = []    
     8             newStr = ''    
     9             index = 0    
    10             # 从字符串single_text逐个取字,直到总长度大于750px    
    11             for item in single_text:    
    12                 newStr += item    
    13             #gitsize可以同时输出字符串的宽和高    
    14                 if font.getsize(newStr.strip())[0] > 750:    
    15                     newlist.append(newStr[:-1])    
    16                     newStr = ''    
    17                     # 如果后面长度没有750px长就返回这部分字符串    
    18                     if font.getsize(single_text[index:])[0] < 750:    
    19                         newlist.append(single_text[index:])    
    20                     else:    
    21                         break    
    22  
    23     
    24                 index += 1    
    25     print(newlist)    
    26     return newlist

    接下来定义函数来画图,传入画图开始的的坐标:x,y值,要画的列表list,以及字体高度和标题文字;做函数的优点就在于不用重复写代码。

    1 def draw_info(x, y, the_list, linehigh, title_text):    
    2     draw.text((x, y), u'%s' % (title_text), color, font)    
    3     for num, info in enumerate(the_list):    
    4         height = num * linehigh    
    5         draw.text((x, y + height + 80), u'%s' % (info), color, font)

    比如绘制“科技新闻”,我们设定好绘画坐标,标题,内容列表等,调用上面的函数即可,其他“科技新闻”,“海外新闻”和“融资收购”类似不做演示,原理相同。

    1 # 绘制科技    
    2 keji_x = title_x - 30    
    3 keji_y = title_y + 88    
    4 title_text = '【科技新闻】'    
    5 keji_text = a[1:gn:2]    
    6 keji_newlist = old_to_new_list(keji_text)    
    7 draw_info(keji_x, keji_y, keji_newlist, linehigh, title_text)

    来看成品

    640?wx_fmt=jpeg

                          日报成品

    3.将日报发送给好友或微信群

    首先引入wxpy库,wxpy是python专门用于调取微信功能的库

    1 from wxpy import *    
    2 import time    
    3 #获取系统时间    
    4 cur_time = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())    
    5 #初始化    
    6 bot = Bot()

    你可以把日报发送给好友,只需要填写好友的昵称,如果要发给多个好友,加入循环结构即可

    1 myfriends = bot.friends().search('好友昵称')[0]    
    2 myfriends.send('python自动早报到了 ' + cur_time)    
    3 myfriends.send_image('日报.jpeg')

    640?wx_fmt=png

     

    1 你也可以选择把日报发送给微信群,操作类似    
    2 groups = ['微信群的名字']    
    3 for send_OBJ in groups:    
    4     my_groups = bot.groups().search(groups)[0]    
    5     my_groups.send('python自动早报到了 ' + cur_time)    
    6     my_groups.send_image('日报.jpeg')

    如果有自己的微信群,需要每天做早报;或者你本身就是互联网运营等职业,相信能给你节约大量的时间!

    做一次的事寻找可行解,重复做的事寻找最优解。如果觉得有料,来个赞,让朋友知道你越来越优秀了。

    转载

    本文转载自csdn,原文链接:https://blog.csdn.net/weixin_42232219/article/details/100137341

    结语

    这个自动发送早报的项目用到了python的采集,绘图,以及聊天机器人等内容。经过本人亲测,可以正常使用,但文中只给出了核心代码,

    还有其他一些内容需要自己稍加改造。现将遇到的问题以及一些思考列举如下:

    1 采集,网站样式有些许改动,需要稍改代码完成采集工作。

    2 如何绘制规整的日报内容,文中所给代码绘制出的内容并不完全规整,需要调整。

    3 原文发信息的时候是文本和图片一起发送的,但是我运行的时候图片就发送不成功,但是把文本注释掉,单独发图片就可以。有知道原因的大佬欢迎留言^_^。

    4 没有实现自动化,标题是每天发早报,难道每天要自己手动运行一次程序吗【狗头】。实现自动化也不难,这里提供3个解决方案:

     1、使用线程的timer 2、使用定时调度 3、使用计划任务

    参考文章

    https://blog.csdn.net/UFv59to8/article/details/78550238
    https://blog.csdn.net/qq_41716680/article/details/100732029
    https://www.cnblogs.com/botoo/p/8622379.html
    https://www.jianshu.com/p/1c8b46982da6
  • 相关阅读:
    MyBatis的几种使用形式。
    laradock开发环境搭建笔记
    前端如何引入vConsole
    技术更迭,一往无前
    博客园使用markdown
    python telnetlib 模块实现功能端口扫描
    kubernetes之ingress部署
    kubernetes之ingress error: endpoints "default-http-backend" not found
    mvc 查询条件回显
    BootStrap 下来菜单点击两次才弹框问题
  • 原文地址:https://www.cnblogs.com/moy-1313133/p/14509557.html
Copyright © 2011-2022 走看看