步行者

自由主义者

wget网站镜像大杀器

今天老婆想下载某个网站的所有网页,然后离线看。我马上就想到了我经常用的wget,最简单的命令就是这样了:
wget -m http://www.example.com/

但是对于某些网页好像没用,下载了首页以后就没直接退出了,娘的,怎么没有迭代啊。用wget -d debug一下:发现有类似语句:
Not following http://www.example/a/ because robots.txt forbids it.
Decided NOT to load it.

原来是robots.txt协议要求的,我不是爬虫,就一次性下载一下,站长不会有意见吧?
对于这种君子协议,wget难道不能偶尔流氓一下?网上一搜,有了,加上这个选项-e robots=off:
wget -m -e robots=off http://www.example.com/

奇怪的是这个选项在wget的help文档中都没有看到,不过这里详细的文档中倒是有:http://www.gnu.org/software/wget/manual/wget.html#Robot-Exclusion。估计这个选项太过刚猛,杀伤力太大。官方文档中也有这些警告:If you know what you are doing and really really wish to turn off the robot exclusion, set the de>robotsde> variable to ‘off’ in your .wgetrc.

另外有些网站也会禁止wget之类agent下载,我们也可以伪装一下,下面是一个比较完美的镜像大杀器语句:
wget -m -e robots=off -U “Mozilla/5.0 (Windows; U; Windows NT 5.1; zh-CN; rv:1.9.1.6) Gecko/20091201 Firefox/3.5.6” “http://www.example.com/”

2009.12.29更新

针对下载下来的网站怎么查看呢?

我是这么解决的:

1、在本机使用一个http server来访问这些网页。我选了apache。每下一个网站,就建立一个虚拟主机,对应你下载的网站。为什么不直接静态访问呢?我知道大部分静态网站内下载下来是直接可以访问的,不需要 http server(这时最好不要用wget -m,用-r应该就可以了),但是如果有些链接是js跳转且跟域名相关的,就很难找到对应的网页了。

2、更改本地的host文件,把网站的域名改为127.0.0.1。当然这样有点麻烦,你要真正访问真实的网站时,需要重新改回来。

3、当然下载的网站都是静态的,所有在服务端处理的脚本都是不能运行的,这是最大的缺点。

2009.12.30更新

昨天又碰到两个问题:

1、注意哪些带参数的超链接在使用wget的时候要用引号引起来,不然wget会认为是两个链接。

2、我碰到另外一个问题是在Windows下面,文件名是不能包含问号的,wget下载下来会保存以@代替,这时页面中的链接地址就不能链到具体文件了。我想到的解决办法是:

1)使用sed之类的程序将文件中所有的链接地址中的?替换为@

2)使用apache2.2.7+的mod_substitute模块实时替换原有的内容。我是选用了这种方法,因为这基本上是一种一劳永逸的方法,不用每次新下载网页都要替换,当然效率会比第一种方法差很多。

2009.12.31更新

经过一晚上的测试,发现无论是apache的mod_substitute模块和mod_rewrite都不是很好用,可能是用得不熟的缘故吧。

不过我发现了wget一个比较有用的参数:-k,也即wget下载完成以后把html文档中所有的连接换成真实的相对连接,这样不用我们手工替换了。


14 Comments
  1. autu 2009-12-29, 00:06:04

    下载之后会储存为啥格式?

  2. XO 2009-12-29, 01:39:25

    @auto
    how to make love 格式

    @Bingo
    刚刚想起来,想租VPS跑程序的话,可以试试 RackSpaceCloud 的 CloudServers,类似于 Amazon EC2 服务,按时间付费,需要的时候建立一个CloudServers,比如跑完三个小时程序关闭 CloudServers,就不收钱了,价格非常便宜。

  3. sunu 2009-12-29, 09:02:02

    to XO, 你觉得RackSpaceCloud大致会是如何实现的?

    如果让我做,我很土的想法是,会不会是通过在页面上的操作(创建/删除/重启等),后台相应地运行一个虚拟机进程(不管是vmware、virtual box或者其它类似技术)。

  4. 小F 2009-12-29, 10:57:58

    远程文件是啥格式的下载到本地的文件就是啥格式的.

  5. ks 2009-12-29, 11:32:44

    js格式的网页有没有管用的方法?

    现在sohu读书之类的网站都是用js链接跳转的。

  6. Bingo 2009-12-29, 13:30:06

    应该都能用吧,我下下来的时候,里面的连接都没改变。所以还要在本地搞一个web server,开一个指向下载目录的虚拟主机,另外再改一下host文件,指向本机。

    现在比较麻烦的是那些动态网页,我发现带‘?’的文件都变成了‘@’,因为Windows是不允许文件名中出现‘?’的。看来还要替换一下。

  7. ks 2009-12-29, 14:13:08

    javascript也能被wget解析?

  8. 小F 2009-12-29, 14:14:21

    wget是下载文件的…只要有文件就能下载,和JS之类的脚本无关吧…

  9. Bingo 2009-12-29, 14:40:30

    to KS:
    wget不负责解析,现在js都是被下载到本地才能用的吧,在服务端的js还没有商业化。而且我连域名都没有改动,这应该也不用改js了吧。

  10. Bingo 2009-12-29, 14:42:50

    不过某个网页里如果有很多域名,倒是个麻烦事。

  11. 卑微的無聊 » 脚本 2010-02-09, 17:35:40

    […] 复制了几个章节后,开始想偷懒的办法。先用wget大杀器,依这个目录先把所有章节都镜像到了本地,然后写个脚本提取.html文件中的相应文字,以前也有写过类似的脚本,php也生疏了,花了近两个小时时间,写好了脚本。。。把所有想要的东西都输出到了text文件中。 […]

  12. bsfmig 2011-02-17, 10:25:22

    我说怎么试图用wget从网易镜像制作fedora本地源不成功,还看到robots.txt,还试图写一个脚本解决问题,难怪。不过倒是初步学了下sed。

  13. 脚本 | 卑微的无聊 2011-08-20, 01:08:14

    […] 复制了几个章节后,开始想偷懒的办法。先用wget大杀器,依这个目录先把所有章节都镜像到了本地,然后写个脚本提取.html文件中的相应文字,以前也有写过类似的脚本,php也生疏了,花了近两个小时时间,写好了脚本。。。把所有想要的东西都输出到了text文件中。 […]


Add your comment

XHTML: You may use these tags: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong> <p>