shell实现论坛灌水机
大概在2年零兩個(gè)月前,我寫過一個(gè)論壇灌水機(jī),前幾天,因?yàn)榕笥岩W(wǎng)絡(luò)投票,又拿出來用了一次,改了下配置文件,又可以當(dāng)投票機(jī)用了。
 由于工作的關(guān)系,現(xiàn)在在UNIX上做開發(fā)了,我嘗試了用UNIX重寫了一個(gè)投票機(jī),深深的體會到,什么叫“一行shell相當(dāng)于1萬行C代碼了”。UNIX天生就是為程序員服務(wù),來幫助他們完成看似不可能的任務(wù)的。
 下面我以我重寫的這個(gè)投票機(jī)為例,來闡述下UNIX的做事風(fēng)格。
 一個(gè)投票機(jī),或曰灌水機(jī),需要具備這么些特性:get/post、數(shù)據(jù)生成、流程控制、并發(fā)支持、代理支持、驗(yàn)證碼識別等等。這些特性基本上是越往后越難的,看看UNIX是怎么用簡單的方式來實(shí)現(xiàn)他們的:
get/post
 UINX提倡用短小精悍的小程序組合來完成復(fù)雜的任務(wù),對于使用HTTP協(xié)議訪問網(wǎng)絡(luò),沒有什么比wget更合用的啦。有UNIX環(huán)境的可以直接在shell下開始嘗試,只有windows的也可以裝一個(gè)cygwin的模擬UNIX環(huán)境來試驗(yàn)。
 在提示符下直接輸入wget,回車
 $ wget
 wget: missing URL
 Usage: wget [OPTION]... [URL]...
Try `wget --help' for more options.
 它提示你缺少URL參數(shù),用--help來獲得更多信息,注意UNIX絕大多數(shù)命令都可以用--help來獲得幫助,而不是dos傳統(tǒng)的/?。
 如果你輸入wget --help后,你會得到所有支持的參數(shù)列表。這些參數(shù)列表對于不怎么會得人來說,可能還是太簡略了,輸入man wget可以獲得更加詳細(xì)的解釋及示例。許多UNIX程序都可以用man加上命令名來得到詳細(xì)的使用說明。
 man的簡要使用如下:
 用上下左右光標(biāo)鍵瀏覽,q鍵退出。g到首行,G到末行,/開始查找,例如/proxy再回車,表示查找含有proxy處,n向下查找下一個(gè),N向上查找下一個(gè)。
 不看幫助,讓我們來猜想最簡單的用法,沒錯(cuò),就是這樣
 $wget www.csdn.net
 --22:10:01--? http://www.csdn.net/
 ?????????? => `index.html'
 Resolving www.csdn.net... 211.100.21.179
 Connecting to www.csdn.net|211.100.21.179|:80... connected.
 HTTP request sent, awaiting response... 200 OK
 Length: 128,038 (125K) [text/html]
100%[====================================>] 128,038??????? 4.29K/s??? ETA 00:00
22:10:46 (2.90 KB/s) - `index.html' saved [128038/128038]
這是不帶選項(xiàng)的用法,網(wǎng)頁自動保存到文件,詳細(xì)過程顯示在終端上。好了,基本的get完成了,算算C代碼要幾行?
 數(shù)據(jù)生成
 對于灌水來說,上節(jié)自然是不夠用的,至少也需要發(fā)送POST數(shù)據(jù)的功能吧?
 這個(gè)簡單,輸入man wget,搜索post,就能找到答案,這里給個(gè)例子:
 $wget www.xxx.com --post-data='a=1&b=2'
 這里有個(gè)地方需要注意的就是,對于命令行中有&的,一定要用''把它引起來,否則會被shell解釋成在后臺運(yùn)行,如上面的例子,如果沒有'',那么shell認(rèn)為是在后臺執(zhí)行"wget www.xxx.com --post-data=a=1",然后又執(zhí)行b=2這樣一個(gè)命令。
 可以傳遞post數(shù)據(jù)了,讀者一定還不滿意,因?yàn)槿绻胱寯?shù)據(jù)變化,例如a要從1變化到1000,總不能手工輸入吧?
流程控制
 好了,這要用到基本的shell編程了。我這里就簡要的給出例子:
 編輯一個(gè)shell文件start.sh,內(nèi)容如下
 #! /bin/sh
 counter=0
 while [ $counter -lt $1 ]
 do
 ??????? counter=`expr $counter +  1`
 ??????? wget "www.xxx.com" "--post-data=a=$counter&b=2"
 done
 保存后,在shell下執(zhí)行chmod +x start.sh, 使這個(gè)腳本可執(zhí)行
 然后執(zhí)行./start.sh 1000,就達(dá)到了我們的目的。
 (這里沒什么好解釋的,我也不喜歡shell的這種循環(huán)、比較與賦值的語法,不過為了它提供的其他好處,只好忍忍啦,畢竟任何事物都不是完美的,需要參考shell語法時(shí)可以查一本書:好像叫<<UNIX和LINUX shell編程指南>>,有電子版)
 也許讀者看到這里,還是覺得UNIX沒什么好的,就剛才這些例子來說,無非是有了一個(gè)用C寫好了的wget程序,我用socket或者用WININET來寫,從功能上來說,哪樣都不少,而且寫熟練了,速度也不慢呀,那我們來看看
并發(fā)支持
 UNIX重來都不考慮多線程這種煩人的東西,諸位把多線程的東西搞清楚了,又調(diào)試出了幾個(gè)多線程的Bug,估計(jì)頭上的白發(fā)沒少生。UNIX下把上一節(jié)那個(gè)腳本在后臺多運(yùn)行幾次,就實(shí)現(xiàn)并發(fā)了,簡單吧,煩人的事情就該交給操作系統(tǒng)去做,而不是在windows中提倡的去搞一個(gè)復(fù)雜無比的多線程程序。
代理支持
 我知道上面的話一定不能讓人心服,現(xiàn)在我舉這個(gè)例子,我覺得能征服至少一半讀者。考慮這樣的任務(wù),你的論壇會限制你灌水的IP,同一個(gè)IP有發(fā)帖間隔限制,或者你要投票的地址限制每個(gè)IP只能投一票,你怎么辦,找代理。那么你覺得需要多長時(shí)間能把這個(gè)功能完成呢?例如說從www.proxycn.com中取大量的代理地址,1天?1000行代碼?有興趣的讀者可以先不往下看,看看在windows的思維方式下,能否在五分鐘內(nèi)完成這個(gè)任務(wù)。
我在剛嘗試這件事時(shí),我也沒考慮要多快,但是我還真就五分鐘內(nèi)做成了。
 第一分鐘,我用瀏覽器打開www.proxycn.com,找到左下角的代理綜合搜索,類型選HTTP,狀態(tài)選活動,點(diǎn)擊搜索按鈕,出來3149個(gè)結(jié)果,共63頁,就是它們了。
 第二分鐘,我復(fù)制第2頁的快捷方式作為wget的參數(shù)
 $wget -O result 'http://www.proxycn.com/proxysearch.php?action=proxys&searchsubmit=yes&address=&port=&AddDateBefore=&AddDateAfter=&status=1'/
 '&isedu=&type=HTTP&type2=&location=&page=2'
 很快,第二頁被下載下來存入result文件了。
 我開始嘗試
 $cat result
 輸出了整個(gè)文件的內(nèi)容,翻動一下屏幕,發(fā)現(xiàn)了一個(gè)好東西onDblClick="clip('219.165.115.186:3128'),運(yùn)氣還不錯(cuò)。
 接著
 $cat result | grep /d{1.3}
 無結(jié)果
 $cat result | grep '/d{1,3}'
 無結(jié)果
 $grep --help | grep perl
 ?-P, --perl-regexp???????? PATTERN is a Perl regular expression
 $cat result | grep -P '/d{1,3}'
 好了,一堆結(jié)果
 $ cat result | grep -P '/d{1,3}/./d{1,3}'
 這下結(jié)果很靠譜,把它匹配完
 $ cat result | grep -P '/d{1,3}/./d{1,3}/./d{1,3}/./d{1,3}:/d{2,5}'
 這下匹配了整個(gè)IP地址加端口了,但是grep是輸出整行的呀,有多余的輸出,
 第三分鐘
 $grep --help
 翻看Output control那一部分,找到一行
 ?-o, --only-matching?????? show only the part of a line matching PATTERN
 試一下
 $ cat result | grep -P '/d{1,3}/./d{1,3}/./d{1,3}/./d{1,3}:/d{2,5}' -o
 203.160.1.47:554
 66.240.123.59:3128
 221.112.144.13:8080
 165.228.129.10:3128
 203.198.69.124:3128
 203.160.1.44:554
 125.247.118.226:3128
 203.160.1.43:554
 203.160.1.52:554
 195.55.133.76:8080
 202.146.67.238:8080
 ...成功了,現(xiàn)在把命令組合一下
 第四分鐘
 編輯proxy.sh文件如下
 #! /bin/sh
 counter=0
 while [ $counter -lt $1 ]
 do
 ??????? counter=`expr $counter + 1`
 ??????? wget  -O - "http://www.proxycn.com/proxysearch.php?action=proxys&searchsu
 bmit=yes&address=&port=&AddDateBefore=&AddDateAfter=&status=1&isedu=&type=HTTP&t
 ype2=&location=&page=$counter" 2>/dev/null | grep  -P '/d{1,3}/./d{1,3}/./d{1,3}/
 ./d{1,3}:/d{2,5}' -o
 done
 然后執(zhí)行chmod +x proxy.sh
 試一下
 $./proxy.sh 1
 沒有問題,現(xiàn)在正式取了
 第五分鐘
 $ ./proxy.sh 63 > result &
 [1] 1680
 這表示任務(wù)在后臺執(zhí)行了,
 我可以用這個(gè)命令來觀察結(jié)果
 $ tail -f result
 大約過了一分鐘,后臺的任務(wù)執(zhí)行完了,我統(tǒng)計(jì)一下行數(shù)
 $ wc -l result
 1749 result
 還真準(zhǔn),剛好3149個(gè)結(jié)果
總結(jié)
以上是生活随笔為你收集整理的shell实现论坛灌水机的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
                            
                        - 上一篇: Java io流详解四
 - 下一篇: aka鉴权 ims_宋月:IMS鉴权过程