今天发现一个比较好的免费下载IT书籍PDF文件的网站,其中有不少好书是别的站点没有的。全站有近5000本书,一一打开页面浏览后再下比较麻烦。由于不用登陆也能下载,于是想简单实用shell编程遍历整个站点的所有页面,获取所有pdf的下载地址,再贴到迅雷里面可以批量下载、离线下载。后续也便于保存和寻找资料。
站点页面的结构是这样的:
num从1编号到500,比较有规律。
这个地址在浏览器中访问,会按照每页10本的量列出整站书籍。通过遍历1到500页,我们首先可以获得这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
这个结果可以直接粘贴到迅雷中,爽爽滴离线下载啦。
原文:http://www.cnblogs.com/zoen/p/5048980.html