使用Python批量抓取单词发音

简介:

备注:今年1月份写的文章,以后准备长期驻扎在这儿,就贴过来了。

        1.12号晚上总算彻底的考完了所有的科目,昨天可以睡一个安稳的懒觉了。从床上爬起来之后,随便从书架上拿了一本书,竟然是《备战大学德语四级考试·词汇篇》,不觉想起当初“战绩辉煌”的德语课。翻开书,看了几个单词后,发现都忘记了该怎么发音,所以想把每个单词的发音放到P3里,等睡不着的时候可以听一听~

        所以,具体需求就是:根据一个文本文件,该文件中提供了一个单词列表,格式为每个单词占一行。需要根据这个列表,从某个网站上把对应单词的发音的mp3文件保存在本地磁盘上,而且mp3文件保存为相应的单词的名称。

         大致就是这些,想想还缺点什么,恩,多线程---典型的多线程应用环境啊。确定一下实现环境,看来Python是首选了。因为快,当然是说开发速度快了~

         该找个网站,从google上搜了搜(最近学校可以用ipv6google了,速度很快,过滤也少),找到一个网站http://www.leo.de/,上面有一个Deutsch–Englisch的图标,当然也有Deutsch –Chinesisch图标,想想欧洲人那种自恃清高的态度,还是果断选了Deutsch-Englisch。随便搜索一个单词,比如“abendessen”,然后会弹出一个列表,点击发音图标的时候,会弹出一个框,框中还有一个推荐网站http://www.dwds.de/。点击之后,感觉风格清新自然简洁。还是输入刚刚那个单词“abendessen”,点击“suche”之后,在浏览器上看到一个URLhttp://www.dwds.de/?qu=abendessen&view=1 view=1区分了是从主页搜索单词还是从搜索单词后弹出的某个页面中搜索的单词两种情况。可以在当前这个页面(http://www.dwds.de/?qu=abendessen&view=1)再输入“abendessen”,点击“suche”后,你会发现URL地址已经改变了,变为:http://www.dwds.de/?qu=abendessen

         再试几个单词后,基本就可以确定每个单词对应的查询页面的URL地址格式为:

http://www.dwds.de/?qu=所查询的单词

接下来就是看下声音地址的组成格式。查看下页面的Html源代码,CTRL+F搜索sound。在刚刚查询“abendessen”的页面中可以找到这样的一个filename: http://media.dwds.de/dwds/media/sound/dwdswb_aussprache_dev/0ddaf706368d33af4d5aca4cebb41f17.mp3。可以基本确信对应于每个单词的mp3文件格式如下:

http://media.dwds.de/dwds/media/sound/dwdswb_aussprache_dev/+单词对应的哈希值.mp3

不知道这里为什么要用哈希值,可以肯定的是不是用来提高检索速度的,因为单词本身就可以作为唯一的键,而且单词的最大长度应该也不会超过一个固定的上限值(比如:40?)。也许使用哈希值是为了防止用程序自动下载发音文件,减少对服务器的冲击吧,我猜。刚看到这个32位的串,我想大家第一反应应该都是猜它是不是单词对应的md5值(比如QQ登录的时候,就对针对密码进行三次md5加密),很不幸的,这个串不是(这个,可以使用Python在交互式模式下做一个简单的验证)。不过这个并不影响下载这个mp3文件,恩,就是先打开页面,然后从页面上找到mp3URL,然后再下载。

         好了,整理一下思路,简单的说,下载一个单词对应的mp3的流程如下:

         Step1:从文件中读取一个单词

         Step2:构造一个单词查询页面的URL,将此URL对应的html源代码保存到content

         Step3:使用正则表达式在content中搜索对应mp3文件的URL

         Step4:读取mp3数据,在本地新建一个文件,把数据保存进去

         Step5:如果没有结束,跳转到Step1

         恩,挺简单的流程。还需要增添的设施就是多线程,测试表明,平均每下载一个单词将近4秒钟,不能在一个线程在访问网络或者保存文件的时候让CPU空闲啊。所以,在运行程序的时候需要传入两个参数,一个就是需要开启的线程的数量,另外一个就是保存单词列表的文件名。不过,等我改天有时间了,实现一个线程池,这样就省事了,把任务扔到池子里就行了。否则在程序中还要考虑加锁解锁这种琐碎的事情,因为保存单词列表的队列是共享资源。这些分析清楚了,差不多就可以写代码了。把代码贴到这儿,仅供参考:

 


 
 
  1. #!/usr/bin/python 
  2.  
  3. #Author:lichao 
  4.  
  5. #Date:01-13-2012 
  6.  
  7. #Description:Download the .mp3 sound files that correspoding to the words in the given file. 
  8.  
  9. import threading 
  10.  
  11. import time 
  12.  
  13. import fileinput 
  14.  
  15. import re 
  16.  
  17. import urllib2 
  18.  
  19. import sys 
  20.  
  21.   
  22.  
  23. class DownloadWorker(threading.Thread): 
  24.  
  25.          global mutext 
  26.  
  27.          def __init__(self,wordsList,workerIndex): 
  28.  
  29.                    threading.Thread.__init__(self
  30.  
  31.                    self.queue=wordsList 
  32.  
  33.                    self.index=workerIndex 
  34.  
  35.          def run(self): 
  36.  
  37.                    print('worker%d start to work' % (self.index)) 
  38.  
  39.                    mutex.acquire() 
  40.  
  41.                    self.word=self.queue.front() 
  42.  
  43.                    mutex.release() 
  44.  
  45.                    while self.word!="0"
  46.  
  47.                             url = "http://www.dwds.de/?qu="+self.word 
  48.  
  49.                             urlContent = urllib2.urlopen(url).read() 
  50.  
  51.                             urlList = re.findall('http://media.dwds.de/dwds/media/sound/dwdswb_aussprache_dev/.*\.mp3', urlContent) 
  52.  
  53.                             try
  54.  
  55.                                      soundData = urllib2.urlopen(urlList[0]).read() 
  56.  
  57.                                      saveName=self.word+".mp3" 
  58.  
  59.                                      output = open(saveName,'wb'
  60.  
  61.                                      output.write(soundData) 
  62.  
  63.                                      output.close() 
  64.  
  65.                                      print('%s:OK                                 --Post by worker%d' % (self.word,self.index) ) 
  66.  
  67.                             except
  68.  
  69.                                      print('%s:FAILED                                   --Post by worker%d' % (self.word,self.index) ) 
  70.  
  71.                             finally
  72.  
  73.                                      mutex.acquire() 
  74.  
  75.                                      self.word=self.queue.front() 
  76.  
  77.                                      mutex.release() 
  78.  
  79.                    print('worker%d eixt' % self.index) 
  80.  
  81. class WordsList(): 
  82.  
  83.          def __init__(self,filePath): 
  84.  
  85.                    self.t=[] 
  86.  
  87.                    for line in fileinput.input(filePath): 
  88.  
  89.                             if(len(line)>1 and line[len(line)-1]=='\n'): 
  90.  
  91.                                      line=line[0:len(line)-1
  92.  
  93.                                      self.t.append(line) 
  94.  
  95.                             else
  96.  
  97.                                      self.t.append(line) 
  98.  
  99.                    self.t.append('0'
  100.  
  101.          def front(self): 
  102.  
  103.                    if(self.t[0]!='0'): 
  104.  
  105.                             return self.t.pop(0
  106.  
  107.                    else
  108.  
  109.                             return self.t[0
  110.  
  111.                             
  112.  
  113. def main(): 
  114.  
  115.          global mutex 
  116.  
  117.          mutex=threading.Lock() 
  118.  
  119.          workerNumber=int(sys.argv[1]) 
  120.  
  121.          filePath=sys.argv[2
  122.  
  123.          wordsList=WordsList(filePath) 
  124.  
  125.          workerPool=[] 
  126.  
  127.          for i in range(0,workerNumber): 
  128.  
  129.                    worker=DownloadWorker(wordsList,i) 
  130.  
  131.                    workerPool.append(worker) 
  132.  
  133.          for i in range(0,workerNumber): 
  134.  
  135.                    workerPool[i].start() 
  136.  
  137.                    
  138.  
  139. if __name__ == "__main__"
  140.  
  141.          main() 

下面两张截图是运行效果图,其中图1是运行效果图。是的,有些单词的mp3下载过程中出错了,这是由于某些单词的发音太简单了,这些单词级别估计是1级,估计是网站的设计者觉得这种简单的单词没有必要制作一个mp3文件放在上面。一般来说,稍难一点的单词的发音都能下载到的。图2是下载后的截图,以后可以用来催眠了。

 

1:下载器运行效果

 



本文转自hipercomer 51CTO博客,原文链接:http://blog.51cto.com/hipercomer/789423

相关文章
|
4月前
|
Python
"揭秘!Python如何运用神秘的正则表达式,轻松穿梭于网页迷宫,一键抓取隐藏链接?"
【8月更文挑战第21天】Python凭借其强大的编程能力,在数据抓取和网页解析领域表现出高效与灵活。通过结合requests库进行网页请求及正则表达式进行复杂文本模式匹配,可轻松提取网页信息。本示例展示如何使用Python和正则表达式解析网页链接。首先确保已安装requests库,可通过`pip install requests`安装。接着,利用requests获取网页内容,并使用正则表达式提取所有`<a>`标签的`href`属性。
52 0
|
2月前
|
数据采集 JSON 数据处理
抓取和分析JSON数据:使用Python构建数据处理管道
在大数据时代,电商网站如亚马逊、京东等成为数据采集的重要来源。本文介绍如何使用Python结合代理IP、多线程等技术,高效、隐秘地抓取并处理电商网站的JSON数据。通过爬虫代理服务,模拟真实用户行为,提升抓取效率和稳定性。示例代码展示了如何抓取亚马逊商品信息并进行解析。
抓取和分析JSON数据:使用Python构建数据处理管道
|
2月前
|
数据采集 Python
python爬虫抓取91处理网
本人是个爬虫小萌新,看了网上教程学着做爬虫爬取91处理网www.91chuli.com,如果有什么问题请大佬们反馈,谢谢。
32 4
|
2月前
|
数据采集 Java Python
如何用Python同时抓取多个网页:深入ThreadPoolExecutor
在信息化时代,实时数据的获取对体育赛事爱好者、数据分析师和投注行业至关重要。本文介绍了如何使用Python的`ThreadPoolExecutor`结合代理IP和请求头设置,高效稳定地抓取五大足球联赛的实时比赛信息。通过多线程并发处理,解决了抓取效率低、请求限制等问题,提供了详细的代码示例和解析方法。
如何用Python同时抓取多个网页:深入ThreadPoolExecutor
|
2月前
|
JSON 数据格式 Python
Python实用记录(十四):python统计某个单词在TXT/JSON文件中出现的次数
这篇文章介绍了一个Python脚本,用于统计TXT或JSON文件中特定单词的出现次数。它包含两个函数,分别处理文本和JSON文件,并通过命令行参数接收文件路径、目标单词和文件格式。文章还提供了代码逻辑的解释和示例用法。
52 0
Python实用记录(十四):python统计某个单词在TXT/JSON文件中出现的次数
|
3月前
|
数据采集 存储 JavaScript
构建您的第一个Python网络爬虫:抓取、解析与存储数据
【9月更文挑战第24天】在数字时代,数据是新的金矿。本文将引导您使用Python编写一个简单的网络爬虫,从互联网上自动抓取信息。我们将介绍如何使用requests库获取网页内容,BeautifulSoup进行HTML解析,以及如何将数据存储到文件或数据库中。无论您是数据分析师、研究人员还是对编程感兴趣的新手,这篇文章都将为您提供一个实用的入门指南。拿起键盘,让我们开始挖掘互联网的宝藏吧!
|
2月前
|
小程序 IDE 开发工具
Python编写单词复习小程序
Python编写单词复习小程序
19 0
|
3月前
|
数据采集 JavaScript 前端开发
构建简易Python爬虫:抓取网页数据入门指南
【8月更文挑战第31天】在数字信息的时代,数据抓取成为获取网络资源的重要手段。本文将引导你通过Python编写一个简单的网页爬虫,从零基础到实现数据抓取的全过程。我们将一起探索如何利用Python的requests库进行网络请求,使用BeautifulSoup库解析HTML文档,并最终提取出有价值的数据。无论你是编程新手还是有一定基础的开发者,这篇文章都将为你打开数据抓取的大门。
|
4月前
|
数据采集 JavaScript 前端开发
构建你的第一个Python爬虫:抓取网页数据入门指南
【8月更文挑战第31天】在数字时代,数据是新的石油。本文将引导初学者通过简单的步骤,使用Python编程语言创建一个基础的网络爬虫程序。我们将探索如何从网络上提取信息,并理解背后的原理。无论你是编程新手还是想要扩展你的技术工具箱,这篇文章都将为你提供一条清晰的道路,让你学会编写能够自动获取网络数据的脚本。准备好开始你的网络数据抓取之旅了吗?让我们现在就开始吧!
|
4月前
|
数据采集 JavaScript 前端开发
Python 爬虫实战:抓取和解析网页数据
【8月更文挑战第31天】本文将引导你通过Python编写一个简单的网络爬虫,从网页中抓取并解析数据。我们将使用requests库获取网页内容,然后利用BeautifulSoup进行解析。通过本教程,你不仅能够学习到如何自动化地从网站收集信息,还能理解数据处理的基本概念。无论你是编程新手还是希望扩展你的技术工具箱,这篇文章都将为你提供有价值的见解。
下一篇
DataWorks