|  | 
 
| 下载51VOA网站上《美语三级跳 Go English》中的文字和音频并非本人一时心血来潮,而是源于论坛网友的一篇求助帖(http://bbs.bathome.net/thread-11802-1-1.html),具体要求为:将http://www.51voa.com/Go_English_1.html这个网站的下级链接采集成文本文件,文本内容包含标题,结尾至“这次的美语三级跳就播送到这里。”如果mp3音频也一并采集下来,最好。 
 从初中到大学,教过本人English的teacher有男有女,惜乎Mister非帅哥,Miss非美眉,所以,本人的鸟语一向不咋地,此实乃本人人生中的一大憾事,因此之故,我对发奋学习English的人一向抱有敬意。既然该网友碰到了学英语中的大难题,那我就尽我所能助人一臂之力吧。
 
 例行公事地开始网页分析。
 
 打开http://www.51voa.com/Go_English_1.html,鼠标四处戳戳点点,左键进入、右键查看、Ctrl+F搜索、尝试下载……捣鼓了好一阵,把它们的家底查了个一清二楚:总共有71个网页及71个mp3需要下载,每个网页中都对应着一个mp3,mp3的下载地址是嵌在这些网页代码中的,而这些网页的真实url,又是在http://www.51voa.com/Go_English_1.html和http://www.51voa.com/Go_English_2.html中被一一罗列了出来,所有的链接都是那么的直白无误,没有丝毫的矜持含蓄,所有的下载动作都无需验证账号密码。
 
 这是个简单的活,我告诉自己。
 
 打开记事本,轻车熟路地码字;再顺手打开cmd.exe窗口,随时做一些小测试。
 
 curl -o 轻轻松松就把 Go_English_1.html 和 Go_English_2.html 下到了本地,htox32c /ip /o0 /u3 再干脆利落地把html文件转换成了文本,保留了原始编码格式,保留了下载链接。
 
 for /f 读取转换后的文本,各种奇形怪状的字符就开始稀里哗啦地在cmd窗口中往下掉——坏了,转换后的文本文件肯定不是ANSI编码!记事本打开那些文本,点“文件/另存为”,一查“编码”栏目,"UTF-8"几个字符白纸黑字异常刺眼。more一下,type一下,竟然还是乱码,倒吸一口凉气:这,这,这,不是逼我出绝招么?
 
 我再也坐不住了,火速奔向白杨大侠的网站:http://baiy.cn,down一个wfr.exe下来,wfr index\*.txt -any -encin:utf-8 -encout:gbk -force,强制转换utf-8为gbk。htox32c.exe到底是小日本写成的工具,竟然没提供unicode转gbk的功能,还是2004年的作品,唉,岁月不饶人啊,不能与时俱进啊。
 
 解决了编码问题,剩下的事情就好办多了:一行行的字符串,直接丢进 for /f 中,findstr过滤过滤,skip=跳过头N行,delims=切分一下,tokens=接收住,set 再替换一下,揉成团、切成片、搓成条……一阵忙活,提出了N多网页地址和mp3文件地址,curl出马,down之!
 
 查看最终结果:70个txt,69个mp3。不对啊,应该是71个txt和71个mp3啊,揉了揉眼睛,再仔细一瞅,没错,就只下了那么多。
 
 排查,赶紧排查,看看少了些什么。
 
 左边世界之窗,右边TotalCommander,鼠标戳了又戳,键盘按了又按,睁大眼睛来来回回扫描了好几次,终于把漏掉的文件找出来了:少了标题为“517 boat...”的网页内容和编号为016a及007b的mp3。
 
 与其他文件相比,它们有什么特殊之处?
 
 先看网页文件,其他的标题都是含有关键词“课程”二字,唯有“517 boat”缺少此标记,恩,看来不能以“课程”作为前后行标记来提取URL,只能更换了。换什么好呢?看看转换后的txt,都有些什么规律。找啊找,终于发现了更直接的标记:URL都以字符串“</Voa_English_Learning/”打头呢,得,赶紧换标记吧,那提取URL的算法也得随之更换了。
 
 再瞅瞅016a和007b的mp3,我左看右看上看下看,看了半天,硬是没能从URL的构成上找到特别之处。URL放到迅雷里一下载,那速度也是嗖嗖的啊;换成其他的mp3链接,那速度更是嗖嗖的啊。嗯哼?哦,似乎016a和007b比其他的下载速度要稍慢,难道这也有问题?try,再try,似乎有点慢,莫非这网站动了什么手脚?百思不得其解,死马当做活马医吧,给curl加 --retry 重试,不行?再加 --retry-delay 延时,还不行?靠,我就不信邪了,下载mp3的代码单列出来,call一下子过程,子过程DownMp3中加检测语句:if not exist "..\result\%~1.mp3" goto DownMp3,你不给我down回来,我就让你给我一直下,累趴下了也非得下回来不可,哼哼,不老实干活就死循环,玩残你!
 
 折腾了老半天,顺手修复了几个小bug,调整了文件保存目录,规范了一下变量名,添加了一些注释……清扫完这些边边角角,世界终于和谐了。
 
 上代码:
 正文中提到的命令行工具可以在这些地方找到:复制代码@echo off
setlocal enabledelayedexpansion
:: 获取含有具体网页下载链接清单的网页
title 获取含有具体下载链接的网页
md index 2>nul
curl -o index\#1.html "http://www.51voa.com/Go_English_[1-2].html"
htox32c /ip /o0 /u3 index\*.html
wfr index\*.txt -any -encin:utf-8 -encout:gbk -force
:: 提取具体网页的下载链接并下载之
cls
title 下载每一个教程的网页文件
md content 2>nul
pushd index
for %%i in (*.txt) do (
    for /f "skip=76 tokens=*" %%j in (%%i) do (
        set "UrlHtml=%%j"
        if "!UrlHtml:~0,23!"=="</Voa_English_Learning/" (
            for /f "tokens=2*" %%k in ("!NameHtml!") do (
                set "NameHtml=%%l"
                set "NameHtml=!NameHtml: =!"
                set "NameHtml=!NameHtml::=:!"
                set "UrlHtml=http://www.51voa.com/!UrlHtml:~1,-1!"
                title 正在下载 %%k_!NameHtml! 的网页数据
                curl -o "..\content\%%k_!NameHtml!.html" "!UrlHtml!"
            )
        )
        set "NameHtml=%%j"
    )
)
popd
:: 下载每一课程中的mp3文件,并提取所有课程中的文字内容分别保存
cls
title 网页转文本
md result 2>nul
pushd content
htox32c /ip /o0 /u3 *.html
wfr *.txt -any -encin:utf-8 -encout:gbk -force
cls
for %%i in (*.txt) do (
    for /f "tokens=*" %%j in ('findstr /i "path\.asp\?url=.*\.mp3" "%%i"') do (
        set "UrlMp3=%%j"
        set "UrlMp3=http://archive.51voa.com/!UrlMp3:~16,-1!"
        title 正在下载 !UrlMp3!
        for /f "delims=_" %%k in ("!UrlMp3!") do set "NameMp3=%%~nk"
        call :DownMp3 "!NameMp3!" "!UrlMp3!"
    )
    title 提取 %%i 的内容
    set over=
    (echo %%~ni&echo.&echo.
    for /f "skip=76 tokens=*" %%j in (%%i) do (
        if "%%j"=="这次的美语三级跳就播送到这里。"  set over=yes
        if "%%j"=="Related Articles"  set over=yes
        if not defined over echo %%j&echo.
    ))>..\result\%%i
)
popd
exit
:DownMp3
curl --retry 3 --retry-delay 2 -o "..\result\%~1.mp3" %2
if not exist "..\result\%~1.mp3" goto DownMp3
goto :eof
 1、Curl.exe:http://curl.haxx.se/(官网)或 http://bbs.bathome.net/thread-1761-1-1.html
 2、HtoX32c.exe:http://win32lab.com/(官网,日文)或 http://bbs.bathome.net/thread-1974-1-1.html(带中文帮助信息)
 3、wfr.exe:http://baiy.cn/utils/wfr/index.htm(官网)
 
 注意事项:由于本代码用到了目录跳转语句,如果把这些命令行工具与批处理文件放在同一目录下的话,处理会出错,建议把它们放在任意一个%path%目录下,推荐放在%SystemRoot%目录下,一般是c:\windows。
 
 [ 本帖最后由 namejm 于 2011-4-10 12:31 编辑 ]
 | 
 |