老习惯,先看看别人的工作。推荐看看 我的知识库(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会出问题,我也不知道什么原因,应该和网络有关。
完