基于wxbot微信框架的微信遥控电视程序

利用wxbot框架和selenium实现微信遥控切换电视频道的应用,支持频道号切换和全屏操作。

最近买了个树莓派,打算在上面部署一点小应用。因此,想到了这个基于wxbot微信框架的遥控电视程序。程序的原理比较简单:对wxbot类进行继承,修改其中的信息处理函数,使其对自己给自己发送的消息进行处理,再根据发送的内容,调用selenium打开chrome浏览器,并播放相应的视频。程序的启动和退出均可通过微信命令遥控。


然而,在开发完之后才发现树莓派上的Raspberry pi系统上装不上flash插件,chrome浏览器也不好装,只能暂时停止移植到树莓派上的计划……

首先宣传一下wxbot框架:github: https://github.com/liuwons/wxBot,作者的csdn: http://blog.csdn.net/tobacco5648/article/details/50722321。这个框架比较好用,只需要继承一下它的wxbot类,再实现一下schedule和handle_msg_all函数就可以实现对微信的各种控制了。

下面是自己的代码。首先拿到tv.cctv/live和tv.cntv/btv1里的链接地址。在tv.cctv/live,拿到右侧的地址有些难度,因此在这里选择了手动添加- _- ||,然后可以对tv.cntv/btv1里的“卫视频道”和“城市频道”标签下的内容做爬虫,同样拿到链接后存储在channel_link.txt文件中。以“城市频道”标签为例,爬虫代码如下:

driver=webdriver.Chrome(executable_path=chromedriver_path,chrome_options=options)
    driver.get('http://tv.cntv.cn/live/btv1')
    WebDriverWait(driver, 3).until(lambda x: driver.find_element_by_id('vplayer'))
    driver.maximize_window()
label=driver.find_element_by_link_text(u'城市频道')
    ActionChains(driver).move_to_element(label)
    channel_file=open('city_channel_new1.txt','a')
    channel_num=53 #前面的“卫视频道”排号到52
    for j in range(2,48,3):
        channel_div=driver.find_elements_by_xpath('//*[@id="channelpane4"]/div['+str(j)+']/div')
        for i in range(1,len(channel_div)+1):
            channel_link=driver.find_element_by_xpath('//*[@id="channelpane4"]/div['+str(j)+']/div['+str(i)+']/div/h3/a')
            channel_info = str(channel_num) + ' ' + channel_link.get_attribute('href') + ' ' + unicode(channel_link.text) + '\n'
            channel_file.writelines(channel_info)
			channel_num+=1
    channel_file.close()

不知道为何channel_info中取channel_link.text取不到……

然后是下面的主程序部分,主要就是对wxbot的继承,实现的sysbot类:

# -*- coding=utf-8 -*-
from wxbot import *
from selenium import webdriver
from selenium.common.exceptions import *
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.common.action_chains import ActionChains
import time

class Systembot(WXBot):
    CHROME_DRIVER_PATH='D:\\WebDrivers\\chromedriver_win32\\chromedriver.exe'
    channel_list=[]
    channel_dict={}
    driver=None
    def __init__(self):
        WXBot.__init__(self)
        self.usr_name = 'self'

以上是一些初始化操作,其中channel_dict存放频道号与频道链接,频道号作为key,链接作为value。

下面是程序的启动函数:

def set_dict(self):
        option=webdriver.ChromeOptions()
        option.add_argument('Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/52.0.2743.116 Safari/537.36')
        option.add_extension('2.3.8_0.crx')
        option.add_extension('cntvLive_20160119.crx')
        channel_file=open('channellink.txt','r')
        self.driver=webdriver.Chrome(executable_path=self.CHROME_DRIVER_PATH,chrome_options=option)
        handles=self.driver.window_handles
        curr_handle=self.driver.current_window_handle
        for h in handles:
            if h!=curr_handle:
                self.driver.switch_to.window(h)
                self.driver.close()
        self.driver.switch_to.window(curr_handle)
        self.driver.maximize_window()
        self.channel_dict['1']=['http://tv.cctv.com/live/cctv1/','CCTV-1']
        self.channel_dict['2']=['http://tv.cctv.com/live/cctv2/','CCTV-2']
        self.channel_dict['3'] = ['http://tv.cctv.com/live/cctv3/','CCTV-3']
        self.channel_dict['4'] = ['http://tv.cctv.com/live/cctv4/','CCTV-4']
        self.channel_dict['5'] = ['http://tv.cctv.com/live/cctv5/','CCTV-5']
        self.channel_dict['6'] = ['http://tv.cctv.com/live/cctv6/','CCTV-6']
        self.channel_dict['7'] = ['http://tv.cctv.com/live/cctv7/','CCTV-7']
        self.channel_dict['8'] = ['http://tv.cctv.com/live/cctv8/','CCTV-8']
        self.channel_dict['9'] = ['http://tv.cctv.com/live/cctvjilu/','CCTV-9']
        self.channel_dict['10'] = ['http://tv.cctv.com/live/cctv10/','CCTV-10']
        self.channel_dict['11'] = ['http://tv.cctv.com/live/cctv11/','CCTV-11']
        self.channel_dict['12'] = ['http://tv.cctv.com/live/cctv12/','CCTV-12']
        self.channel_dict['13'] = ['http://tv.cctv.com/live/cctv13/','CCTV-13-新闻']
        self.channel_dict['14'] = ['http://tv.cctv.com/live/cctvchild/','CCTV-14-少儿']
        self.channel_dict['15'] = ['http://tv.cctv.com/live/cctv15/','CCTV-15-音乐']
        self.channel_dict['16'] = ['http://tv.cctv.com/live/cctv5plus/','CCTV-5+']
        for line in channel_file:
            self.channel_dict[line.split(' ')[0]]=[line.split(' ')[1],' ']
        channel_file.close()

采用带扩展程序的方式通过selenium启动chrome浏览器。其中,2.3.8_0.crx是Adguard插件,去除广告;而cntvlive.crx为cntv的插件。去除广告的原因在于为了使播放时自动全屏,需模拟双击视频的方式,然而有广告存在的话就会点到广告从而进入广告页面,而那个handle部分是因为调用Adguard插件会启动很多Tab页,会占用较多资源,因此将多余的标签页全部关闭,只保留最后打开的那个。

随后向字典中添加内容,手动+从文件读取两种方式。

最后一部分:处理微信信息

def handle_msg_all(self, msg):
        if msg['msg_type_id']==1:
            if self.channel_dict.has_key(msg['content']['data']):
                self.driver.get(self.channel_dict[msg['content']['data']][0])
                if int(msg['content']['data'])<17:
                    WebDriverWait(self.driver,3).until(lambda x:self.driver.find_element_by_id('hds_flash_player'))
                    video = self.driver.find_element_by_id('hds_flash_player')
                else:
                    WebDriverWait(self.driver, 3).until(lambda x: self.driver.find_element_by_id('vplayer'))
                    video = self.driver.find_element_by_id('vplayer')
                time.sleep(5)
                ActionChains(self.driver).double_click(video).perform()
                ActionChains(self.driver).double_click(video).perform()
            if unicode(msg['content']['data']) == u'get':
                self.set_dict()
            elif unicode(msg['content']['data']) == u'full':
                try:
                    video = self.driver.find_element_by_id('hds_flash_player')
                except NoSuchElementException:
                    video = self.driver.find_element_by_id('vplayer')
                ActionChains(self.driver).double_click(video).perform()
                ActionChains(self.driver).double_click(video).perform()
            elif unicode(msg['content']['data']) == u'exit':
                self.driver.quit()
                sys.exit(0)

msg_type_id为1时表示是自己发送的消息。随后就是根据消息的内容判断要执行的功能,发送的消息为频道号,为1-109。由于央视频道采用的播放器和其他频道采用的播放器不一样,因此还需根据频道号判断页面的视频元素的id号。

这里使用了WebDriverWait智能等待的方式,使视频一出来马上进入全屏。值得注意的是ActionChains这个函数,虽然函数名为double_click,但经试验发现实际上执行的是单击操作,因此需要连续调用两次才能使视频全屏。

full命令是当视频万一没有自动全屏时,可以发送这条命令手动令视频进入全屏状态。

主函数:

# -*- coding=utf-8 -*-
from systembot import Systembot


if __name__=='__main__':
    systembot=Systembot()
    systembot.run()


程序运行效果:

首先会显示二维码,用微信扫一下登录。


然后输入get并发送给自己:


稍等片刻,浏览器开启



输入频道号并发送:


进入画面:



换台及全屏:




Ok。

这个基于wxbot的微信遥控电视程序就到此结束。由于微信可能会有延迟,因此导致换台时可能反应不是很及时;此外,地方台不知为何无法自动全屏,需要输入full命令手动全屏。


可惜这个东西现在暂时无法部署到树莓派上……或者,有谁知道如何在树莓派上装iso格式的ubuntu-mate或flash视频插件的也可以告诉我,争取把它移植到树莓派上,从而将树莓派变成一个移动机顶盒。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值