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

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

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

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

该找个网站,从google上搜了搜(最近学校可以用ipv6的google了,速度很快,过滤也少),找到一个网站http://www.leo.de/,上面有一个Deutsch–Englisch的图标,当然也有Deutsch –Chinesisch图标,想想欧洲人那种自恃清高的态度,还是果断选了Deutsch-Englisch。随便搜索一个单词,比如“abendessen”,然后会弹出一个列表,点击发音图标的时候,会弹出一个框,框中还有一个推荐网站http://www.dwds.de/。点击之后,感觉风格清新自然简洁。还是输入刚刚那个单词“abendessen”,点击“suche”之后,在浏览器上看到一个URL是http://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文件,恩,就是先打开页面,然后从页面上找到mp3的URL,然后再下载。

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

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

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

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

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

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

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

  1. #!/usr/bin/python
  2. #Author:lichao
  3. #Date:01-13-2012
  4. #Description:Download the .mp3 sound files that correspoding to the words in the given file.
  5. import threading
  6. import time
  7. import fileinput
  8. import re
  9. import urllib2
  10. import sys
  11. class DownloadWorker(threading.Thread):
  12. global mutext
  13. def __init__(self,wordsList,workerIndex):
  14. threading.Thread.__init__(self)
  15. self.queue=wordsList
  16. self.index=workerIndex
  17. def run(self):
  18. print('worker%d start to work' % (self.index))
  19. mutex.acquire()
  20. self.word=self.queue.front()
  21. mutex.release()
  22. while self.word!="0":
  23. url = "http://www.dwds.de/?qu="+self.word
  24. urlContent = urllib2.urlopen(url).read()
  25. urlList = re.findall('http://media.dwds.de/dwds/media/sound/dwdswb_aussprache_dev/.*\.mp3', urlContent)
  26. try:
  27. soundData = urllib2.urlopen(urlList[0]).read()
  28. saveName=self.word+".mp3"
  29. output = open(saveName,'wb')
  30. output.write(soundData)
  31. output.close()
  32. print('%s:OK                                 --Post by worker%d' % (self.word,self.index) )
  33. except:
  34. print('%s:FAILED                                   --Post by worker%d' % (self.word,self.index) )
  35. finally:
  36. mutex.acquire()
  37. self.word=self.queue.front()
  38. mutex.release()
  39. print('worker%d eixt' % self.index)
  40. class WordsList():
  41. def __init__(self,filePath):
  42. self.t=[]
  43. for line in fileinput.input(filePath):
  44. if(len(line)>1 and line[len(line)-1]=='\n'):
  45. line=line[0:len(line)-1]
  46. self.t.append(line)
  47. else:
  48. self.t.append(line)
  49. self.t.append('0')
  50. def front(self):
  51. if(self.t[0]!='0'):
  52. return self.t.pop(0)
  53. else:
  54. return self.t[0]
  55. def main():
  56. global mutex
  57. mutex=threading.Lock()
  58. workerNumber=int(sys.argv[1])
  59. filePath=sys.argv[2]
  60. wordsList=WordsList(filePath)
  61. workerPool=[]
  62. for i in range(0,workerNumber):
  63. worker=DownloadWorker(wordsList,i)
  64. workerPool.append(worker)
  65. for i in range(0,workerNumber):
  66. workerPool[i].start()
  67. if __name__ == "__main__":
  68. main()

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

图1:下载器运行效果

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

使用Python批量抓取单词发音相关推荐

  1. python爬虫学习基础教程,批量抓取美女图片!

    python的抓取功能其实是非常强大的,当然不能浪费,呵呵.下面就与大家分享一个python写的美女图自动抓取程序吧! 其中用到urllib2模块和正则表达式模块.下面直接上代码: 用python批量 ...

  2. qpython爬虫_python爬虫教程:批量抓取 QQ 群信息

    前言 本文讲解Python批量抓取 QQ 群信息,包括群名称.群号.群人数.群主.地域.分类.标签.群简介等内容,返回 XLS / CSV / JSON 结果文件. 基本环境配置 版本:Python2 ...

  3. python 爬取作品集_Python批量抓取站酷ZCOOL作品图片并归档

    前言 前几天,由于个人有需求,所以就要对站酷网一些类别下的作品的图片进行批量抓取,首先是采用的是NodeJs来写的,但是在运行的途中遇到很多的问题,所以后来就换成了Python,同时使用了多线程,使得 ...

  4. Python利用bs4批量抓取网页图片并下载保存至本地

    Python利用bs4批量抓取网页图片并下载保存至本地 使用bs4抓取网页图片,bs4解析比较简单,需要预先了解一些html知识,bs4的逻辑简单,编写难度较低.本例以抓取某壁纸网站中的壁纸为例.(b ...

  5. python爬取新浪微博数据中心_Python爬虫框架Scrapy实战之批量抓取招聘信息

    网络爬虫抓取特定网站网页的html数据,但是一个网站有上千上万条数据,我们不可能知道网站网页的url地址,所以,要有个技巧去抓取网站的所有html页面.Scrapy是纯Python实现的爬虫框架,用户 ...

  6. python批量读取图片并批量保存_Python爬虫:批量抓取花瓣网高清美图并保存

    原标题:Python爬虫:批量抓取花瓣网高清美图并保存 昨天看到了不错的图片分享网--花瓣,里面的图片质量还不错,所以利用selenium+xpath我把它的妹子的栏目下爬取了下来,以图片栏目名称给文 ...

  7. python爬虫ip代理_python爬虫批量抓取ip代理的方法(代码)

    本篇文章给大家带来的内容是关于python爬虫批量抓取ip代理的方法(代码),有一定的参考价值,有需要的朋友可以参考一下,希望对你有所帮助. 使用爬虫抓取数据时,经常要用到多个ip代理,防止单个ip访 ...

  8. python爬虫:批量抓取代理ip,进行验证,抓取豆瓣网站影视信息

    本文作为学习笔记参考用: [1]批量抓取代理ip: 找到第三方ip代理的网站,进行分析,并批量抓取,抓取程序放到Proxies_spider.py中,如下所示: import re import re ...

  9. python Web抓取(一)[没写完]

    需要的模块: python web抓取通过: webbrowser:是python自带的,打开浏览器获取指定页面 requests:从因特网上下载文件和网页 Beautiful Soup:解析HTML ...

  10. Python爬虫抓取考试试题

    Python爬虫抓取考试试题 今天做了个小玩意,但觉得挺有意思的,分享给大家.主要是这样的,因为帮妹子寻找考试资料,发现同一本书不同的章节分别在不同的链接中,复制起来实在要命,所以就在想能不能用爬虫实 ...

最新文章

  1. RabbitMQ(四):RabbitMQ与Spring Boot简单整合 快速尝鲜版
  2. C#筛法求出范围内的所有质数
  3. centos7 docker升级到最新稳定版本
  4. Boost:获取随机数的实例
  5. ibatis与spring的整合
  6. 自动产生fsm代码的工具_代码自动生成工具
  7. python数据库安装_python数据库-MySQL安装问题总结(48)
  8. pgsql thinkphp5_thinkphp 连接postgresql
  9. 数据行业工作3年,我靠这7个能力,成为领导青睐的高级数据分析师
  10. c# xls 复制一行_C# 复制Excel单元格格式
  11. struts2 helloworld
  12. POJ:3126-Prime Path
  13. linux集群100道单选题面试试题系统工程师中级试题(4)
  14. Windows安全加固系列---日志配置操作
  15. 敏捷开发Sprint周期总结
  16. mysql设置bufferpool_mysql修改buffer_pool大小
  17. 解决IE浏览器无法删除证书的问题
  18. python基于django校园信息管理平台设计与实现(项目源码+视频录制+截图)
  19. 查看linux下tomcat启动日志
  20. 数学实验教程matlab版实验报告,MATLAB数学实验报告.doc

热门文章

  1. idea使用mvn命令打包报错 不可用
  2. Borderline-SMOTE算法介绍及Python实现【内附源代码】
  3. 气象数据 常用下载网站
  4. 哈工大车万翔教授:ACL 2010-2020研究趋势总结
  5. SATA工作模式咋选?揭秘AHCI和IDE区别(全文)
  6. matlab常用了滤波函数小结
  7. MATLAB的卡尔曼滤波函数与实例
  8. 基于贝叶斯决策理论的分类方法
  9. 世界各国国家代号与区号
  10. 【算法】冒泡排序图文讲解