免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 1951 | 回复: 0

CMD与Curl双剑合璧:自动合并多页主题 [复制链接]

论坛徽章:
0
发表于 2009-11-21 15:29 |显示全部楼层
CMD与Curl双剑合璧:自动合并多页主题
现实需求
当遇到长串经典的讨论帖;
当看到分多页的软件教程;
当发现让人爱不释手的连载小说的时候。
如何保存这些有很多分页的内容就成为了一件冗杂而又枯燥的机械劳动。
无论是手工复制还是依靠软件保存,都需要大量的人为干预,这是身为智慧生物的我们所不能容忍的。
既然计算机的出现就是替代人进行一些繁复的工作的,那为什么不把尽可能多的工作扔给它们呢?
可惜豆腐目前还没有发现一款软件可以满足我的要求,既然没有现成的可用那就自己动手吧。
思路分析
要解决一个问题必须先有一个环境,毕竟一个方案不可能通吃所有问题。我们就先设问题是要合并论坛中常见的多页主题。
要合并一个多页主题,我们首先得获取这个主题的每一个分页的内容,这种重复性的工作让机器来做是再适合不过的了。
其次我们需要分辨用户贴出的内容从哪里开始,在哪里结束。这部分第一次需要人来完成,后面的就交给机器吧。
最后我们需要获取我们需要的内容并把它重新组织起来生成最终的成果,这同样只需机器就可以很好的完成。
只要我们满足了上面三点,我们就可以把自己从重复劳动中解救出来做其它的事情了。
解决方案
由于高级语言需要专门的学习和配套的软件,这无形提高了应用的难度,最终豆腐选择了用CMD命令行来完成这个工作。
当然,CMD命令中是没有获取网页内容的功能的,我们还需要
Curl
这个强大的命令行工具来助我们一臂之力。
我们就以合并
CCF精品技术论坛

MPlayer 2006-03-03 K&K 更新在 992 楼
为例,顺着刚才的思路来一步步尝试以达到最终的Goal。
网页抓取
在Curl的帮助下,我们可以轻松的通过命令行来抓取我们想要的网页:
CODE:  
[Copy to clipboard]

curl -o tmp1.txt http://bbs.et8.net/bbs/showthread.php?t=634659&page=1&pp=15这样我们就把该主题第一页的内容保存在了tmp1.txt文件中。
对于某些需要检测浏览器信息的网站,我们可以用
CODE:  
[Copy to clipboard]

-A "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0)"来伪装成IE浏览器。
对于需要使用cookies的网站,我们可以用
CODE:  
[Copy to clipboard]

-D cookie1.txt来保存cookies,用
CODE:  
[Copy to clipboard]

-b cookie1.txt来读取cookies。
对于防盗链的网站,我们可以用
CODE:  
[Copy to clipboard]

-e "http://bbs.et8.net/"来伪装成从某个相关联接进入的。 再与CMD中强大的 FOR 命令和变量相结合,加上人类的小小智慧,就可以打造出自动抓取该主题的全部内容的脚本。
分析该主题的URL,我们可以知道 page= 表示页数,这为自动化处理提供了基础,同时我们知道该主题有73页,最终的抓取脚本如下:
CODE:  
[Copy to clipboard]

@echo off
setlocal ENABLEDELAYEDEXPANSION
set last=1
for /l %%i in (1,1,73) do (
echo %%i
curl -b cookie!last!.txt -D cookie%%i.txt -A "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0)" -e "http://bbs.et8.net/bbs/showthread.php?t=634659^&page=!last!^&pp=15" -o tmp%%i.txt http://bbs.et8.net/bbs/showthread.php?t=634659^&page=%%i^&pp=15
set /a last=%%i-1
)
copy tmp*.txt temp.txt
del cookie*.txt
del tmp*.txt
endlocal将上面脚本保存为 grab.cmd 运行后我们就的到了保存了该主题全部73页内容的 temp.txt 文件。
内容分析
由于CMD字符处理的问题,我们先把 temp.txt 另存为 ANSI 编码。
分析单页的内容后豆腐发现该论坛程序在用户内容开始之前有一个每页唯一的 ,
而在结束的时候有一个同样唯一的  ,这正是我们所希望找到的可以作为标志位的地方。
文本处理
由于 FOR 命令一次只能以同样的规则处理一行的内容,于是豆腐便采用 FOR 嵌套的方式来处理整个大文件。
先用
CODE:  
[Copy to clipboard]

for /f "delims=" %%i in (temp.txt) do ( echo %%i >tmp.txt )将 temp.txt 的内容一次一行地写入 tmp.txt。
再套用另一个 FOR 来处理 tmp.txt 的一行。
标志设置
我们可以通过 FOR 的 delims= 和 tokens= 参数来分割和保存一行的内容
我们用
CODE:  
[Copy to clipboard]

for /f "tokens=1-3 delims== " %%j in (tmp.txt)参数设定以 ""、"-"、"="、" "来分割一行,
并把分割后的前三段内容存入 %%j %%k %%l 三个变量中。接着我们用 if 语句来判断这三个变量是否符合设置标志位的条件:
CODE:  
[Copy to clipboard]

if "%%j"=="div" if "%%k"=="id" if %%l=="posts" set flag=1
if "%%j"=="start" if "%%k"=="content" if "%%l"=="table" set flag=0flag=1 代表用户内容开始,flag=0代表用户内容结束。
内容剪裁
由于CMD命令行处理的限制,HTML中的注释开始符号 "CODE:  
[Copy to clipboard]

for /f "tokens=1-8 delims=" if not "%%s"=="-->" if not "%%r"=="-->" if not "%%q"=="-->" if not "%%p"=="-->" if not "%%o"=="-->" if not "%%m"=="ECHO" if !flag!==1 echo %%i >>new.htm)同时,我们也完成了把开始标志位后的内容存入 new.htm 的工作。
最终脚本
CODE:  
[Copy to clipboard]

@echo off
setlocal ENABLEDELAYEDEXPANSION
set flag=0
for /f "delims=" %%i in (temp.txt) do (
echo %%i >tmp.txt
for /f "tokens=1-3 delims== " %%j in (tmp.txt) do (
if "%%j"=="div" if "%%k"=="id" if %%l=="posts" set flag=1
if "%%j"=="start" if "%%k"=="content" if "%%l"=="table" set flag=0
for /f "tokens=1-8 delims=" if not "%%s"=="-->" if not "%%r"=="-->" if not "%%q"=="-->" if not "%%p"=="-->" if not "%%o"=="-->" if not "%%m"=="ECHO" if !flag!==1 echo %%i >>new.htm
)
)
)
del tmp.txt
endlocal保存脚本为 merge.cmd 运行后得到合并出的 new.htm 文件就是该主题全部1083帖的内容。
优化改进
该脚本只完成了抓取文本内容的工作,我们还可以通过判断 IMG 元素来找到图片内容,
并把 src 属性后面的路径补完成完整路径,就可以正确显示出内容中的图片。
后记总结
CMD和Curl相结合可以完成很多批量的复杂工作,虽然第一次多花点时间,但之后就可以方便的使用了。
该脚本可以顺利抓取合并CCF精品技术论坛的任意主题以及部分基于vBulletin的论坛,但对于其它论坛还需要分别修改才可使用。


本文来自ChinaUnix博客,如果查看原文请点:http://blog.chinaunix.net/u/11065/showart_2100029.html
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP