小程序主页:法语记忆 学背单词动词变位
更新内容
v3.4.0 更新的主要内容就只有以下一点:
- 增加了单词的真人发音。
音频提取
真人发音来源
根据Forvo 版权页面的描述 In the same manner, the user can use the pronunciations and translations made available in Forvo Media S.L. in any way as long as they are not used for commercial purposes.
,用户可以在除了商业用途之外使用这些音频文件,并且在 Forvo 上为注册用户提供了下载功能。那么本节就来说说如何批量获取这些音频文件。
和之前使用的 BeautifulSoup 不同,BeautifulSoup
爬取比较快速,适合提取网页文本信息(* 没用过完整功能,表述可能不合适);而Selenium
可以调用浏览器进行爬取,自动化及动态操作,这里主要用它模拟鼠标点击和初期模拟登录,但其速度比较慢。
通过 chrome 浏览器右键检查Forvo
音频的下载按钮,我并没有明显地看出文件下载地址,所以像BeautifulSoup
这样的工具对于我来说就没有Selenium
行之有效。不过搜了一下发现了使用Scrapy
爬取Forvo
音频的例子,链接在此。简单来说,就是把Selenium
当作一个鼠标精灵
。
准备工作
- 首先是安装
Anaconda
- 搜索
Anaconda Prompt
并打开 - 输入并执行:
pip install selenium
- 根据自己使用的浏览器版本下载对应的
webdriver
,这里以 chrome 浏览器为例:chrome 浏览器对应的 webdriver 下载点击这里。 - 将下载好的
chromedriver
文件解压后放到目录:C:\Users\用户名\Anaconda3\Scripts
下,即Anaconda
的安装目录下。
音频提取
- 导入各种库。
from selenium import webdriver
import pandas as pd
import random
import time
- 读取 excel 中的单词列表,并以数组的方式显示。
read_result = pd.read_excel('freq2020.xlsx', 'temp', index_col=None, na_values=['NA'])
freq = read_result.to_numpy()
i = 0
freq_list = []
while i<len(freq) :
freq_list.append(freq[i][0])
i=i+1
print(freq_list)
- 如果使用的是 chrome 浏览器,如果需要登录才能操作:填入网站的登录页面,使其自动登录:
driver = webdriver.Chrome()
driver.get("https://zh.forvo.com/login/") # 想要处理的网站登陆页面
- 自动填入用户名、密码,自动登录。
username="邮箱"
passwd="密码"
driver.implicitly_wait(10)
elem=driver.find_element_by_name("login")
elem.send_keys(username)
elem=driver.find_element_by_name("password")
elem.send_keys(passwd)
driver.find_element_by_class_name("button").click()
- 观察自己需要处理的网站的网址规律,自行组织链接结构,例如
https://zh.forvo.com/word/法语单词/#fr
:
url = "https://zh.forvo.com/word/"
url = url + <法语单词>+"/#fr"
driver.get(url)
driver.implicitly_wait(10)
接下来就是去找该页面上的元素,并进行点击。查找元素的方式有以下这些,具体的使用方法可以查看selenium
的文档。
- find_element_by_id
- find_element_by_name
- find_element_by_xpath
- find_element_by_link_text
- find_element_by_partial_link_text
- find_element_by_tag_name
- find_element_by_class_name
- find_element_by_css_selector
右击页面中的下载图标,选择检查
(如上图),观察页面元素。这里使用了xpath
进行页面元素的定位。关于xpath
的详细使用方式可以参照这里。
在本例中:
//div
选取所有 div 标签子元素。//div[@id='language-container-fr']
选取 div 标签中 id 为language-container-fr
的元素。//div[@id='language-container-fr']//p[@class='download']
选取 div 标签中 id 为language-container-fr
中 p 标签的 class 为download
的元素。
driver.find_element_by_xpath("//div[@id='language-container-fr']//p[@class='download']").click()
小程序音频播放
最简单的代码就是直接获取小程序云存储的音频文件链接即可播放单词音频,但是实际操作中发现一些问题:获取一个单词音频大概需要消耗流量10kb
左右,若用户没有听清则需要反复获取该单词发音。这样的话5GB的云存储CDN流量
其实用的挺快的(虽然目前用户很少 🤣)。
所以为了节省 CDN 流量和用户的数据流量:就将音频下载为临时文件
,然后在当前页面第二次及以上播放时(比方说听一遍没听清)播放临时链接
。在进入下一个页面时理论上会自动销毁临时音频文件,下次遇见再次从云端获取。
real_vocal: function() {
if (app.globalData.vocal == null) { //如果从来没有播放过该单词音频,则下载之
var learn_word = app.globalData.learn_word; //获取当前的单词
const audio = wx.createInnerAudioContext() //小程序音频新的接口,官方推荐使用
wx.cloud.downloadFile({ //下载音频,变位缓存文件并生成临时链接
fileID: "cloud://观察链接,修改此部分" + learn_word + ".mp3", // 文件 ID
success: res => {
// 返回临时文件路径
app.globalData.vocal = res.tempFilePath
console.log(res.tempFilePath)
audio.src = app.globalData.vocal //音频来源(临时链接)
audio.play() //播放音频
},
fail: console.error
})
} else { //否则,重复播放音频临时链接(以节省CDN流量)
const audio = wx.createInnerAudioContext()
audio.src = app.globalData.vocal
audio.play()
}
},
参考资料
- https://www.w3school.com.cn/xpath/xpath_syntax.asp
- https://blog.csdn.net/weixin_42551465/article/details/80817552
- https://zh.forvo.com/word/je/
- https://blog.csdn.net/lijun538/article/details/50695914
- https://selenium-Python-zh.readthedocs.io/en/latest/locating-elements.html
- https://sites.google.com/a/chromium.org/chromedriver/downloads