标题: [网络工具] 下载51VOA网站上《美语三级跳 Go English》中的文本及音频 [打印本页]
作者: namejm 时间: 2011-4-9 01:36 标题: 下载51VOA网站上《美语三级跳 Go English》中的文本及音频
本帖最后由 namejm 于 2011-4-10 12:29 编辑
下载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。
作者: Batcher 时间: 2011-4-9 19:34
wfr会被某些杀软误杀
作者: asnahu 时间: 2011-4-9 21:07
本帖最后由 asnahu 于 2011-4-10 07:39 编辑
- curl http://www.51voa.com/Go_English_[1-2].html | sed -n "/list/{:a s/[^\x22]\+[^l]\x22//; //ta; s/\x22G[^\n]\+n>/\x22/g; s/\/V/http:\/\/www.51voa.cm&/g; s/\x22/\n/g; p}" | wget -i -
复制代码
作者: namejm 时间: 2011-4-9 23:49
而mp3的url地址,刚好和相应网页的文件名相对应。
mp3的文件名和课程名并不完全对应,比如编号为016a的网页,对应的mp3为ge016a_22sep2010.mp3。类似的还有好几个,还是得老老实实地去具体帖子里查看。
当然,用批处理只是提供了一种途径,还有其他的方法可以办到。
作者: jh1688 时间: 2011-4-10 06:46
我用楼主的批处理无法下载,调试了一下发现在几个地方用上指定路径就OK了。我是一个菜鸟,说得不一定正确请指教:- @echo on
- 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
复制代码
作者: namejm 时间: 2011-4-10 12:24
哦,对了,我的那些命令行工具都是放在C:\Windows目录下的,不会因为频繁的跳转路径而找不到路径,如果把那些命令行工具放在批处理当前目录下的话会找不到的,忘了说明了,更新一下。
作者: Vast 时间: 2011-4-10 20:27
十分感谢老大鼎力之助,若不发奋学习,实有辜负之嫌。
作者: wc726842270 时间: 2011-4-10 21:49
和LZ的另外一篇文章有点像
http://bbs.bathome.net/thread-11728-1-1.html
当然是大体方面了.呵呵
欢迎光临 批处理之家 (http://bathome.net./) |
Powered by Discuz! 7.2 |