今天发现一个比较好的免费下载IT书籍PDF文件的网站,其中有不少好书是别的站点没有的。全站有近5000本书,一一打开页面浏览后再下比较麻烦。由于不用登陆也能下载,于是想简单实用shell编程遍历整个站点的所有页面,获取所有pdf的下载地址,再贴到迅雷里面可以批量下载、离线下载。后续也便于保存和寻找资料。

站点页面的结构是这样的:

http://domain/page/num

num1编号到500,比较有规律。

这个地址在浏览器中访问,会按照每页10本的量列出整站书籍。通过遍历1500页,我们首先可以获得这5000本书的detail页面地址,而每本书的pdf下载地址就在这个detail页面中。

在mac或者linux中编写形如以下的shell代码,并运行之:

 

#!/bin/bash

for k in $( seq 1 500 )

do

echo "page "${k}" start"

echo "---------------------"

curl http://domain/page/${k}/ | grep bookmark | grep h2 >> result.txt

Done

 

通过这段代码,我们循环遍历了500个页面,在屏幕上打印当前处理到哪一页了,并添加分隔线。

代码使用curl命令去访问拼接出来的页面地址,并根据返回结果中书籍detail页地址所在行的关键字进行过滤,过滤出来的行追加写到result.txt文件中。

这段shell可以拆成多份运行,将seq后的取值范围分段即可,并行提高爬取效率。

 

最终得到的result是一个含有5000行书籍detail页地址的文本文件。

将这个文本文件中的html标签都替换掉后,剩下的每一行都是可直接访问的detail页连接,形如:http://domain/bookname/。

再次编写一个shell脚本,来遍历这5000行detail页,以获取其中包含的最终的pdf下载链接:

#! /bin/bash 

for LINE in `cat result.txt` 

do  

count1=`cat final_res.log | wc -l`

echo ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

echo $count1

        echo $LINE start

        echo   

        curl --connect-timeout 10 -m 15 $LINE | grep '.pdf"' >> final_res.log

        count2=`cat res1.log | wc -l`

        if [ $count1 -eq $count2 ]; then echo $LINE >> timeout.log

        fi

 

done

在这段代码中,我们读取result.txt文件,并将它的逐行取出,进行curl访问。

Final_res.log文件存放最终的pdf下载地址,而curl访问超时的result行则写入timeout.log,以后再次访问。

这里我们对curl命令增加了参数,定义其去连接一个地址的时间不超过10秒,而数据传输的时间不超过15秒,以提高爬取效率。

在curl执行前后,我们通过cat final_res.log | wc -l获取最终结果文件的行数,如果行数没有变化的话,则认为curl命令超时了,其访问的连接要提出来放到timeout中,以后再访问。

为了提高效率,我们也可以将result.txt文件拆成多份,使用相应的shell代码同时去爬取内容。

这样,我们得到的最终的final_res.log文件中,再将html标签清除干净,获得的结果形如下:

http://domain/date1/filename1.pdf

http://domain/date2/filename2.pdf

 

http://domain/daten/filenamen.pdf

 

这个结果可以直接粘贴到迅雷中,爽爽滴离线下载啦。

posted on 2015-12-15 17:54  zoen  阅读(276)  评论(0编辑  收藏  举报