About This Blog

This is Chunhao's Blog

I'm writing something about life and technology here. As a practice of English writing.

My Chinese Blog: http://blog.chunhao.net

My Chinese Page: http://chunhao.net/index-cn.html

Subscribe

The books I’m reading

The items I’m interested in

License

24 February 2009 - 0:12How to write an auto-downloading script

如何写一个自动下载的脚本?

用Linux有一个很好的地方就是你可以很方便地让计算机为你做体力活。当然,前提是你要了解Linux的思维方式。下面就是一个活生生的例子,大家可以看看用Linux是怎么做事情的。

如果你喜欢听评书,这里是个不错的地方。这个网站有很多评书,还有百家讲坛,甚至有声的金庸小说。上面的东西不光可以在线听,而且都可以免费下载,不用注册。但是,只能一个链接一个链接地下载。例如,如果想下载《大唐惊雷》第1回,就要进入一个页面,然后点下载;要下载第2回,就要进入另一个页面,然后再点下载。这样,就无法批量下载一整部评书了。

如果你用Windows,那么你要么人肉点击这些链接,一个一个地下载(可能有100+回);要么就用C或者Java写一个程序自动下载,前提是你要懂网络编程的细节。

下面,我就说一说在Linux下如何用Shell写一个自动下载脚本:

首先要做的就是分析链接,这个网站上,包含有《大唐惊雷》从第1回到第100回的链接的页面都是很有规律的:

http://www1.5ips.net/down_19_001.htm

http://www1.5ips.net/down_19_002.htm

http://www1.5ips.net/down_19_100.htm

我们需要一个东西能从001递增到100,递增可以用一个for循环解决,但是要输出成001,002这样的就不是很直接。在C语言中,我们可以用printf(“%03d”, n)来解决,在Shell中也一样,可以用printf命令:

printf "%03d" $i

此时,包含1-100回链接的页面地址已经生成了,下一步就是要从这些页面中提取出下载链接。如果分析这些页面的源代码,我们可以发现下面代码:

<li><a href="http://dx23a.52ps.cn/pingshu/单田芳_大唐惊雷/单田芳_大唐惊雷_001.mp3?0000060.191.99.1203tflag=1235403802opin=5d44be8c1fba6271d12369537d33a135&amp;ip=60.191.99.1.mp3"><font color="blue">点此下载《大唐惊雷》第001回</font></a><br /></li>

我们可以用grep来获得这行。

那么,如何获得里面的下载链接?用sed或者awk也能达到目的,可以我都不会。我用了Python,string有一个split函数,这里按照引号(“)把这行分开,形成一个list,然后提取适当的元素就可以获得下载链接。用同样的方法还可以获得文件名,例如:”单田芳_大唐惊雷_001.mp3″。

大体的方法就是想法就是这样,下面就是具体的脚本:

#!/bin/sh
 
siteurl="http://www1.5ips.net/"
prefix="down_192_"
startnum=1
endnum=100
 
for i in `seq $startnum $endnum`
do
    preurl=$siteurl$prefix`printf "%03d" $i`".htm"
    wget -q -O prehtml $preurl
    iconv -f GBK -t utf-8 prehtml | grep 点此下载 &gt; down_url_line
    down_url=`./geturl.py`
    filename=`./getname.py`
    echo "Starting downloading $i..."
    echo $down_url
    echo $filename
    wget -O $filename $down_url
    echo "Finish downloading $i"
done
#!/usr/bin/python
# getname.py
 
r = open("down_url_line").read().split('/')
print r[5].split('?')[0]
#!/usr/bin/python
# geturl.py
 
r = open("down_url_line").read().split('"')
print r[1]

运行脚本之后,大约1个小时,整个100回评书就下完了。当然,脚本还有很多改进的余地,比如说通过参数传入评书的名字,然后自动获取链接前缀。

在Linux下解决问题就是这么简单?在Windows下呢?现在了解网络编程,然后打开VS,稀里糊涂写一堆代码,然后再写一个窗口?然后再复杂的跟踪、调试、修改……有兴趣的话你可以试一试。 :)

需要说明的是,我对Shell脚本和不是很熟,有时for或者while循环的格式都忘了;Python也不懂,我还没用Python写过程序。所有的东西都是现用现学,现用现Google。

Share and Enjoy:
  • Digg
  • del.icio.us
  • TwitThis
  • Google Bookmarks
  • Facebook
  • Reddit
  • Slashdot
  • MySpace

3 Comments | Tags: linux, programming

Comments:

    • Chunhao says:

      恩,果然可以,我土了。
      我还以为它还要核对每次的地址中的opin
      多谢啊

      • Enson says:

        圡了吧?。。。flashget早在n多年前就支持这个批量下载了。
        关键人家那管理得绝对比wget好
        而且如果我没记错,wget应该是单线程的吧。。。

Add a Comment

*
To prove you're a person (not a spam script), type the security word shown in the picture. Click on the picture to hear an audio file of the word.
Click to hear an audio file of the anti-spam word