[Python]从爱词霸下载单词读音音频文件

主要功能

  • 输入单词下载读音文件
  • 文件保存到单词开头字母的目录下
  • 可选英音或美音,默认为美音

系统环境

  • Windows 7 Ultimate 32-bit
  • Python 2.6.6 + BeautifulSoup 模块

代码

#!/usr/bin/env python
# -*- coding: utf-8 -*-

"""从爱词霸下载单词读音音频文件
"""

import urllib2
import re
import os
from BeautifulSoup import BeautifulSoup, SoupStrainer

def get(word, headers=None, lang='US'):
    """获取音频文件链接
    >>> get('receipt')
    

    """
    # 设置 header
    user_agent = ('Mozilla/5.0 (Windows NT 6.1; rv:9.0) '
                  + 'Gecko/20100101 Firefox/9.0')
    if headers is None:
        headers = {'User-Agent' : user_agent}
    url ='http://www.iciba.com/%s/' % urllib2.quote(word)
    # 读取网页内容
    request = urllib2.Request(url=url, headers=headers)
    try:
        html = urllib2.urlopen(request).read()
    except:
        print u'网络故障!'
        return None
    else:
        # 获取发音所在链接标签
        links = SoupStrainer('a', title=re.compile(ur'真人发音|电脑合成语音'))
        if links:
            audios = [str(tag) for tag in BeautifulSoup(html, parseOnlyThese=links)]
            soup = BeautifulSoup(''.join(audios))
            audios = soup.findAll('a')
            # print audios
            if 'US' in lang.upper() and len(audios) > 1: # 'US'
                audio = audios[1]['onclick'].split("'")[1]
            else: # 'UK'
                audio = audios[0]['onclick'].split("'")[1]
            return audio
        else:
            return None

def save(url, word, headers=None, savedir=''):
    """保存音频文件
    """
    if url is None:
        print u'无音频文件可下载!'
    else:
        # 设置 header
        user_agent = ('Mozilla/5.0 (Windows NT 6.1; rv:9.0) '
                      + 'Gecko/20100101 Firefox/9.0')
        if headers is None:
            headers = {'User-Agent' : user_agent}
        headers['Referer'] = 'http://www.iciba.com/%s/' % urllib2.quote(word)
        # 读取网页内容
        request = urllib2.Request(url=url, headers=headers)
        try:
            file_data = urllib2.urlopen(request).read()
        except:
            print u'网络故障!'
        else:
            starts = 'abcdefghijklmnopqrstuvwxyz'
            if not savedir:
                savedir = '.'
            # 将文件保存到单词开头字母的文件夹中
            for i in starts:
                if word.startswith(i):
                    savedir = savedir + os.sep + i
                    break
            else:
                savedir = savedir + os.sep + '0-9'
            if not os.path.exists(savedir):
                os.makedirs(savedir)
            # 保存后的文件路径
            file_name = savedir + os.sep + word +'.mp3'
            # print file_name
            # 如果文件名已存在
            if os.path.exists(file_name):
                print u'同名文件已存在!'
            else:
                with open(file_name,'wb') as output:
                    # 写入数据,即保存文件
                    output.write(file_data)

def main():
    while True:
        word = raw_input("> ").strip()
        if not word: break
        save(get(word, lang='uk'), word, savedir='audio')

if __name__ == '__main__':
    main()

最新版本:get_iciba_word_audio/audio.py

[python] IOError: [Errno 2] No usable temporary directory found in [‘/tmp’, ‘/var/tmp’, ‘/usr/tmp’, ‘/data1/www/htdocs/405/webpytest/1’]

前段时间使用 SAE 时,出现一个有关临时文件目录的错误。

错误信息

IOError: [Errno 2] No usable temporary directory found in [‘/tmp’, ‘/var/tmp’, ‘/usr/tmp’, ‘/data1/www/htdocs/405/webpytest/1’]

原因

由于没有 SAE 的系统临时文件目录的可写权限,所以报临时目录错误。

解决

手动指定程序所用的具有可写权限的临时目录

import tempfile
tempfile.tempdir = 'tempdir'
# tempfile.tempdir = sae.core.get_tmp_dir() # SAE 平台的临时目录

ps1. sae.core.get_tmp_dir() 目录暂时不具有可写权限,会报错。

ps2. 未指定临时目录时, Python 会在以下列表中查找具有可写权限的目录:

Python查找一个标准目录列表, 将第一个用户有权限在其中创建文件的目录来设置tempdir . 这个列表是:

  1. 环境变量TMPDIR中的目录名.

  2. 环境变量TEMP中的目录.

  3. 环境变量TMP中的目录.

  4. 平台指定的位置:

    • 在RiscOS上, 由Wimp$ScrapDir指定目录名字.
    • 在Windows上, 以C:$backslash$TEMP, C:$backslash$TMP, $backslash$TEMP, 和 $backslash$TMP按序查找目录.
    • 在其他平台上, 以/tmp, /var/tmp, 和/usr/tmp按序查找目录.
  5. 最后一个是当前工作目录.

更新 sae.core.get_tmp_dir() 不能用的问题

在index.wsgi最前面打上这个patch,可以临时绕过本地文件系统的tempfile

但是需要注意上传文件过大的问题

import os

import tempfile
import cStringIO

def TemporaryFile(mode='w+b', bufsize=-1, suffix="",
                   prefix='', dir=None):
    return cStringIO.StringIO()
tempfile.TemporaryFile = TemporaryFile

import sae
import sae.storage

参考