老習慣,先看看別人的工作。推薦看看 我的知識庫(1)--Java 搜索引擎的實現— 網絡爬蟲 文章把相關概念講的很詳細了。
老樣子,我也是初學者,通過本次學習主要掌握以下幾點:
1.了解python 網絡編程
2.了解python多線程鎖機制
3.掌握python re模塊match使用
那么開始吧
使用urllib模塊
1 def getWebPage(url): 2 wp = urllib.urlopen(url) 3 content = wp.read() 4 return content
2.對抓取到的網頁內容進行分析,提取有用URL
抓到的數據是用str存儲的,下面使用python里的re.split()和re.match()
1 def analysisPage(content): 2 strlist = re.split('\"',content) 3 urlset = set([]) 4 for str in strlist: 5 if re.match('http://www.cnblogs.com(/|\w)+', str): 6 urlset.add(str + '\n') 7 return list(urlset)
園里關於python的html解析的文章很多,看的我眼花繚亂,這里就不一一列舉了。
這里有個問題,我把match里的pattern改成 ’http://www.cnblogs.com(/|\w)+html$' 就
匹配不出結果了,不知道什么原因,哪位大神知道。
3.多線程
主要用了一個urllist和一個urlset。
urlset用來存儲已經訪問過的網頁url,urllist用來存儲待訪問的網頁url
申請四個線程並行的對urllist的url進行頁面抽取,提取頁面url加入到urllist中
為了互斥使用urllist和urlset,引入了listlock和setlock兩把鎖
全部代碼如下:
1 import re 2 import urllib 3 import threading 4 5 def getWebPage(url): 6 wp = urllib.urlopen(url) 7 content = wp.read() 8 return content 9 10 def analysisPage(content, urllist, urlset): 11 strlist = re.split('\"',content) 12 geturlset = set([]) 13 for str in strlist: 14 if re.match('http://www.cnblogs.com/(/|\w)+', str): 15 geturlset.add(str + '\n') 16 17 setlock.acquire() 18 geturlset = geturlset - urlset 19 setlock.release() 20 21 listlock.acquire() 22 for url in list(geturlset): 23 urllist.append(url) 24 listlock.release() 25 26 class MyThread(threading.Thread): 27 def __init__(self, urllist, urlset): 28 threading.Thread.__init__(self) 29 self.urllist = urllist 30 self.urlset = urlset 31 32 def run(self): 33 while True: 34 listlock.acquire() 35 if self.urllist: 36 url = self.urllist.pop(0) 37 listlock.release() 38 else: 39 listlock.release() 40 break 41 42 setlock.acquire() 43 if len(self.urlset) >= 50: 44 setlock.release() 45 break 46 else: 47 if url in self.urlset: 48 setlock.release() 49 continue 50 else: 51 self.urlset.add(url) 52 setlock.release() 53 content = getWebPage(url) 54 analysisPage(content, self.urllist, self.urlset) 55 56 listlock = threading.RLock() 57 setlock = threading.RLock() 58 59 if __name__ == '__main__': 60 starturl = 'http://www.cnblogs.com/\n' 61 content = getWebPage(starturl) 62 #urlset存放已訪問過的網頁url 63 #urllist存放待訪問的網頁url 64 urlset = set([starturl]) 65 urllist = [] 66 analysisPage(content, urllist, urlset) 67 tlist = [] 68 for i in range(4): 69 t = MyThread(urllist, urlset) 70 t.start() 71 tlist.append(t) 72 for t in tlist: 73 t.join() 74 f = open('url.txt', 'w') 75 f.writelines(list(urlset)) 76 f.close()
當urlset集合的元素超過50時就停止,當這個數值較大時,socket會出問題,我也不知道什么原因,應該和網絡有關。
完