多線程功能是linux中非常成熟的一個功能了,下面我們介紹linux多線程網頁截圖功能,下面有兩個例子,一個是python另一個是shell,具體我們來看看吧.
shell多線程網頁截
linux的兩個截圖工具cutycapt和phantomjs,經過測試,cutycapt截圖較慢,但比較穩定,phantomjs截圖速度較快,但時有出現進程假死的狀態,權衡利弊,決定使用cutycapt+shell腳本的方式截圖.
- webshot.sh
 - #/bin/bash
 - #webhsot
 - #by caishzh 2013
 - WEBSHOTDIR="/data/webshot"
 - mkdir -p $WEBSHOTDIR
 - while read LINE
 - do
 - DISPLAY=:0 cutycapt --url=http://$LINE --max-wait=90000 --out=$WEBSHOTDIR/$LINE.jpg >/dev/null 2>&1
 - done<domain.txt
 
腳本很簡單,就不注釋了,domain.txt是網址列表,cutycapt的安裝和使用參照這里,執行腳本,可以正常截圖,圖片質量也很高,但另一個問題出現了,對幾萬個網站截圖,時間周期太長,估算需要半個月左右.
時間太長,耗不起,需要優化下腳本,找了下資料,決定使用多線程截圖,其實shell無法實現多線程,只是將多個進程放入后臺執行而已.
- multiwebshot.sh
 - #/bin/bash
 - #Multithreading webshot
 - #by caishzh 2013
 - WEBSHOTDIR="/data/webshot"
 - mkdir -p $WEBSHOTDIR
 - #將domain.txt分割成10個文件(x開頭),每個文件5000行
 - split -l 5000 domain.txt
 - for i in `ls x*`;do
 - {
 - for j in `cat $i`;do
 - DISPLAY=:0 cutycapt --url=http://$j --max-wait=90000 --out=$WEBSHOTDIR/$j.jpg >/dev/null 2>&1
 - done
 - }&
 - done
 - wait
 - #刪除由spilt分割出的臨時文件
 - rm x* -f
 
腳本說明:先使用split將domain.txt分割成多個個文件,每個文件5000行,再使用兩個嵌套的for循環實現多進程截圖,第一個for是列出由split分割的的文件名,第二個for對這些文件里的網站截圖,注意大括號后面的&,&的作用是將大括號里的腳本代碼放到后臺執行,這就模擬處理“多線程”的效果,實際則是多進程,wait是等待前面的后臺任務全部完成才往下執行.
使用該腳本大大提高了截圖的是速度,在兩天左右的時間里完成所有網站的截圖,效果顯著,需要注意的是,cutycapt截圖是需要占用較大的網絡帶寬和cpu資源,在配置較差的機器上不要開太多的cutycapt“線程”,以免造成機器死機.
python多線程網頁截
剛好最近在學習python,而python可以很方便的支持多線程,找了些資料,使用threading+queue的方式實現了“能者多勞”的多線程截圖方式.
- #coding:utf-8
 - import threading,urllib2
 - import datetime,time
 - import Queue
 - import os
 - class Webshot(threading.Thread):
 - def __init__(self,queue):
 - threading.Thread.__init__(self)
 - self.queue=queue
 - def run(self):
 - while True:
 - #如果隊列為空,則退出,否則從隊列中取出一條網址數據,并截圖
 - if self.queue.emptyempty():
 - break
 - host=self.queue.get().strip('/n')
 - shotcmd="DISPLAY=:0 cutycapt --url=http://"+host+" --max-wait=90000 --out="+host+".jpg"
 - os.system(shotcmd)
 - self.queue.task_done()
 - time.sleep(1)
 - def main():
 - queue=Queue.Queue()
 - f=file('domain.txt','r')
 - #往隊列中填充數據
 - while True:
 - line=f.readline()
 - if len(line)==0:
 - break
 - queue.put(line)
 - #生成一個 threads pool, 并把隊列傳遞給thread函數進行處理,這里開啟10個線程并發
 - for i in range(0,10):
 - shot=Webshot(queue)
 - shot.start() //Vevb.com
 - if __name__=="__main__":
 - main()
 
程序描述如下:
1、創建一個Queue.Queue() 的實例,將domain.txt里的網站列表存入到該隊列中.
2、for循環生成10個線程并發.
3、將隊列實例傳遞給線程類Webshot,后者是通過繼承 threading.Thread 的方式創建的.
4、每次從隊列中取出一個項目,并使用該線程中的數據和 run 方法以執行相應的工作
5、在完成這項工作之后,使用 queue.task_done() 函數向任務已經完成的隊列發送一個信號.
新聞熱點
疑難解答