#encoding: gb2312 import urllib2 import threading import logging import re import sys import os from bs4 import BeautifulSoup reload(sys) sys.setdefaultencoding("utf-8") #日誌初始化 FILE = os.getcwd() logging.basicConfig(filename=os.path.join(FILE, 'log.txt'),level=logging.DEBUG) #待抓取的任務隊列 url_new = [('none','http://www.111cn.net/')] #已完成的任務 url_old = [] #已完成的狀態 url_err = {200:[]} #鎖 lock = threading.Lock() lock2= threading.Lock() #線程執行主方法 #從工作清單中擷取一條url進行抓取 #分析url,去重複,將得到的urls重新放入工作清單 #儲存當前url的訪問狀態 def geturl(): global url_new try: while True: lock.acquire() if len(url_new)<=0: lock.release() continue url_t = url_new.pop(0) url = url_t[1] try: req = urllib2.urlopen(url) except urllib2.HTTPError, e: #記錄到對應的列表中 if url_err.has_key(e.code): url_err[e.code].append((url,url_t[0])) else: url_err[e.code] = [(url,url_t[0])] with open('log.html', 'a+') as f: f.write(str(e.code)+':'+url+', 來路:'+url_t[0]+'<br>') continue else: url_err[200].append(url) with open('log.html', 'a+') as f: f.write('200:'+url+', 來路:'+url_t[0]+'<br>') #記錄到已訪問的列表中 url_old.append(url) #開始提取頁面url soup = BeautifulSoup(req.read().decode('UTF-8', 'ignore')) alink= soup.find_all('a', attrs={'href':re.compile(".*?xxxxxx.*?")}) tmp_url = [] for a in alink: href = a.get('href') tmp_url.append(a.get('href') if a.get('href').find('http:')>=0 else 'http://www.xxxxxx.com'+a.get('href')) tmp_url= {}.fromkeys(tmp_url).keys() for link in tmp_url: if link not in url_old: url_new.append((url, link)) tmp = [] for i in xrange(len(url_new)): if url_new[i][1] not in tmp: tmp.append(url_new[i][1]) else: del url_new[i] #url_new = {}.fromkeys(url_new).keys() #輸出一下狀態資訊 os.system('cls') print threading.Thread().getName()+":當前線程數:"+str(threading.activeCount())+",當前剩餘任務量:"+str(len(url_new))+", 已訪問:"+str(len(url_old)) for k in url_err.keys(): print str(k)+':'+str(len(url_err[k])) lock.release() except Exception as e: logging.debug(str(e)) lock.release() #線程數檢測 死迴圈持續檢測當前活動線程數 #不夠數量時自動建立啟動新線程 def threadcheck(num): t=threading.Thread(target=geturl) t.start() t.join() #定義主方法 def main(): """初始 建立200個線程 for i in xrange(190): t = threading.Thread(target=geturl) threads.append(t) for i in xrange(190): threads[i].start() for i in xrange(190): threads[i].join()""" t = threading.Thread(target=threadcheck, args=(10,)) t.start() t.join() #geturl(url_new.pop(0))
#開始 if __name__ == '__main__': main() input('整站抓取已結束!') |