赤脚论坛[原临沮论坛]

 找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 17520|回复: 6

[文档] 利用爬虫和树莓派3打造自己的语音天气闹钟

[复制链接]
     
鲜花(0) 鸡蛋(0)
完美的我 发表于 2017-7-31 16:46 | 显示全部楼层 |阅读模式 来自 湖北省宜昌市 电信

赶紧注册,享受更多功能!查看帖内大图!

您需要 登录 才可以下载或查看,没有账号?立即注册

x
本帖最后由 完美的我 于 2017-7-31 18:14 编辑

准备
  • 树莓派3
  • 小音箱
环境
python 3.4
获取所在位置天气
这里选择墨迹天气获取实时天气信息,地址:
墨迹天气的官方网址自己搜索,我发不了外部的url地址
进入墨迹天气的页面,墨迹天气会根据你的ip加载相应地区的天气。

这次我们主要抓取温度、天气、湿度、风力、空气质量和天气提示这几个数据。
这种小爬虫我们就不用Scrap那种重型武器啦,使用requests和BeautifulSoup这两个超级好用的库可以快速实现。
首先依次输入下列两行命令安装好requests和BeautifulSoup库。
pip3 install requests
pip3 install beautifulsoup4
爬虫代码如下所示:
import re
import requests
from datetime import datetime
from bs4 import BeautifulSoup


headers = {
        'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit'
                      '/537.36 (KHTML, like Gecko) Chrome/53.0.2785.143 Safar'
                      'i/537.36',
    }

res2 = requests.get('墨迹天气网址', headers=headers)

soup = BeautifulSoup(res2.text, "html.parser")
temp = soup.find('div', attrs={'class': 'wea_weather clearfix'}).em.getText()
weather = soup.find('div', attrs={'class': 'wea_weather clearfix'}).b.getText()
sd = soup.find('div', attrs={'class': 'wea_about clearfix'}).span.getText()
sd_num = re.search(r'\d+', sd).group()
sd = sd.replace(sd_num, sd_num_zh)
wind = soup.find('div', attrs={'class': 'wea_about clearfix'}).em.getText()
aqi = soup.find('div', attrs={'class': 'wea_alert clearfix'}).em.getText()
aqi_num = re.search(r'\d+', aqi).group()
aqi = aqi.replace(aqi_num, aqi_num_zh)
info = soup.find('div', attrs={'class': 'wea_tips clearfix'}).em.getText()
sd = sd.replace(' ', '百分之').replace('%', '')
aqi = 'aqi' + aqi

today = datetime.now().date().strftime('%Y年%m月%d日')
text = '早上好!今天是%s,天气%s,温度%s摄氏度,%s,%s,%s,%s' % \
       (today, weather, temp, sd, wind, aqi, info)
命令行播放语音
使用mplayer实现语音播放,通过以下命令安装mplayer:
sudo apt-get install mplayer
文字转语音
刚开始想通过python的库实现本地文字转语音,在windows系统下没有问题,但树莓派3上中文无法转换。后来就找到了百度的文字转换语音API,地址:官方网址自己搜索,我发不了外部的url地址
还可以选各种声音,调节语速。虽然它没有给出直接的api接口,但是我们利用含有谷歌内核的浏览器的开发者模式可以找到api。我用的qq浏览器
打开开发者模式,点击播放的按钮,在network里就可以找到刚刚发出的请求。

就我们要找的百度文字转语音API,其中per是参数是语音的类型,spd是语速,vol是音量,而tex则是需要转换的文字。通过以下代码就可以实现将特定的文字转换为语音。
import os

url = u'前面加上http:/分个/tts这里是英文小点baidu.com/text2audio?idx=1&tex={0}&cuid=baidu_speech_' \
      u'demo&cod=2&lan=zh&ctp=1&pdt=1&spd=4&per=4&vol=5&pit=5'.format(text)
os.system('mplayer "%s"' % url)
实现定时播放语音
我们使用crontab来实现每天定时启动程序。
  1. 30 07 * * * /usr/bin/python3 /home/pi/Documens/Python/weather_voice.py
复制代码
这个地方我没有尝试
Ps:注意crontab中的路径要使用绝对路径。
具体的crontab用法就不在这里一一讲解了,大家随便搜索一下就有很多
结尾
中间还遇到了一些小bug,比如说语音转文字的过程中数字只能一个一个的念出来,做为一个完美主义者肯定不能忍受这个,12摄氏度给我播报成一二摄氏度怎么行!!!所以就写了一个小函数专门转换数字为中文。最后所有的代码整合起来就是这样啦。不过貌似最新的百度语音已经修复了这个功能
由于帖子字数限制,完整代码将发在另一
作者 woodenrobot
http冒号//player.youku.com/player.php/sid/XMjkzNDg3MDg4NA==/v.swf
1.png
1.png
百姓地盘、草根平台!手机访问论坛,更方便更快捷!
点击修改为自己的签名)本站客服QQ:
     
鲜花(0) 鸡蛋(0)
 楼主| 完美的我 发表于 2017-7-31 16:46 | 显示全部楼层 来自 湖北省宜昌市 电信
看了楼主的帖子,我只想说一句很好很强大!
百姓地盘、草根平台!手机访问论坛,更方便更快捷!
点击修改为自己的签名)本站客服QQ:
     
鲜花(0) 鸡蛋(0)
 楼主| 完美的我 发表于 2017-7-31 16:46 | 显示全部楼层 来自 湖北省宜昌市 电信
不管你信不信,反正我是信了。
百姓地盘、草根平台!手机访问论坛,更方便更快捷!
点击修改为自己的签名)本站客服QQ:
     
鲜花(0) 鸡蛋(0)
 楼主| 完美的我 发表于 2017-7-31 16:48 | 显示全部楼层 来自 湖北省宜昌市 电信
本帖最后由 完美的我 于 2017-7-31 16:50 编辑

此为完整代码
import os
import re
import time
import requests
from datetime import datetime, timedelta
from bs4 import BeautifulSoup
headers = {
        'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit'
                      '/537.36 (KHTML, like Gecko) Chrome/53.0.2785.143 Safar'
                      'i/537.36',
    }
def numtozh(num):
    num_dict = {1: '一', 2: '二', 3: '三', 4: '四', 5: '五', 6: '六', 7: '七',
                8: '八', 9: '九', 0: '零'}
    num = int(num)
    if 100 <= num < 1000:
        b_num = num // 100
        s_num = (num-b_num*100) // 10
        g_num = (num-b_num*100) % 10
        if g_num == 0 and s_num == 0:
            num = '%s百' % (num_dict[b_num])
        elif s_num == 0:
            num = '%s百%s%s' % (num_dict[b_num], num_dict.get(s_num, ''), num_dict.get(g_num, ''))
        elif g_num == 0:
            num = '%s百%s十' % (num_dict[b_num], num_dict.get(s_num, ''))
        else:
            num = '%s百%s十%s' % (num_dict[b_num], num_dict.get(s_num, ''), num_dict.get(g_num, ''))
    elif 10 <= num < 100:
        s_num = num // 10
        g_num = (num-s_num*10) % 10
        if g_num == 0:
            g_num = ''
        num = '%s十%s' % (num_dict[s_num], num_dict.get(g_num, ''))
    elif 0 <= num < 10:
        g_num = num
        num = '%s' % (num_dict[g_num])
    elif -10 < num < 0:
        g_num = -num
        num = '零下%s' % (num_dict[g_num])
    elif -100 < num <= -10:
        num = -num
        s_num = num // 10
        g_num = (num-s_num*10) % 10
        if g_num == 0:
            g_num = ''
        num = '零下%s十%s' % (num_dict[s_num], num_dict.get(g_num, ''))
    return num
def get_weather():
    # 下载墨迹天气主页源码
    res = requests.get('http英文冒号//tianqi.moji.com/', headers=headers)
    # 用BeautifulSoup获取所需信息
    soup = BeautifulSoup(res.text, "html.parser")
    temp = soup.find('div', attrs={'class': 'wea_weather clearfix'}).em.getText()
    temp = numtozh(int(temp))
    weather = soup.find('div', attrs={'class': 'wea_weather clearfix'}).b.getText()
    sd = soup.find('div', attrs={'class': 'wea_about clearfix'}).span.getText()
    sd_num = re.search(r'\d+', sd).group()
    sd_num_zh = numtozh(int(sd_num))
    sd = sd.replace(sd_num, sd_num_zh)
    wind = soup.find('div', attrs={'class': 'wea_about clearfix'}).em.getText()
    aqi = soup.find('div', attrs={'class': 'wea_alert clearfix'}).em.getText()
    aqi_num = re.search(r'\d+', aqi).group()
    aqi_num_zh = numtozh(int(aqi_num))
    aqi = aqi.replace(aqi_num, aqi_num_zh).replace(' ', ',空气质量')
    info = soup.find('div', attrs={'class': 'wea_tips clearfix'}).em.getText()
    sd = sd.replace(' ', '百分之').replace('%', '')
    aqi = 'aqi' + aqi
    info = info.replace(',', ',')
    # 获取今天的日期
    today = datetime.now().date().strftime('%Y年%m月%d日')
    # 将获取的信息拼接成一句话
    text = '早上好!今天是%s,天气%s,温度%s摄氏度,%s,%s,%s,%s' % \
           (today, weather, temp, sd, wind, aqi, info)
    return text
def text2voice(text):
    url = 'http英文冒号//tts英文句号baidu.com/text2audio?idx=1&tex={0}&cuid=baidu_speech_' \
          'demo&cod=2&lan=zh&ctp=1&pdt=1&spd=4&per=4&vol=5&pit=5'.format(text)
    # 直接播放语音
    os.system('mplayer "%s"' % url)
def main():
    # 获取需要转换语音的文字
    text = get_weather()
    print(text)
    # 获取音乐文件绝对地址
    mp3path2 = os.path.join(os.path.dirname(__file__), '2.mp3')
    # 先播放一首音乐做闹钟
    os.system('mplayer %s' % mp3path2)
    # 播报语音天气
    text2voice(text)
if __name__ == '__main__':
    main()
百姓地盘、草根平台!手机访问论坛,更方便更快捷!
点击修改为自己的签名)本站客服QQ:
     
鲜花(4) 鸡蛋(0)
年轻就是资本 发表于 2017-8-1 09:30 | 显示全部楼层 来自 湖北省宜昌市 移动
小手一抖,金币拿走。
百姓地盘、草根平台!手机访问论坛,更方便更快捷!
点击修改为自己的签名)本站客服QQ:
     
鲜花(7) 鸡蛋(0)
冰凌儿 发表于 2017-8-1 14:57 | 显示全部楼层 来自 湖北省宜昌市 电信
百姓地盘、草根平台!手机访问论坛,更方便更快捷!
点击修改为自己的签名)本站客服QQ:
     
鲜花(19) 鸡蛋(0)
荆山野女 发表于 2017-8-1 17:30 | 显示全部楼层 来自 广东省珠海市香洲区 电信
姐顶的不是寂寞,是楼主的帖!
百姓地盘、草根平台!手机访问论坛,更方便更快捷!
点击修改为自己的签名)本站客服QQ:
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|Archiver|手机版|小黑屋|简介|联系我们|赤脚网 ( 鄂ICP备18015422号-4 )

GMT+8, 2024-5-5 22:54

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

网站内容仅代表网友个人观点,非本站认同之观点!删帖请用删帖卡,或联系【 bbs@yalj.net 】我们会尽快处理。
声明:严禁任何人以任何形式在本站发表与中华人民共和国法律相抵触的言论!
技术管理:远安坤哥    主办单位:远安县临沮网信息管理中心
                   
快速回复 返回顶部 返回列表