您的位置:首页 > 编程语言 > Python开发

使用python多线程实现一个简单spider

2012-07-01 10:54 1121 查看
老习惯,先看看别人的工作。推荐看看 我的知识库(1)--Java 搜索引擎的实现— 网络爬虫 文章把相关概念讲的很详细了。

老样子,我也是初学者,通过本次学习主要掌握以下几点:

1.了解python 网络编程

2.了解python多线程锁机制

3.掌握python re模块match使用

那么开始吧

[b]1.使用python抓取一个网页的内容[/b]

使用urllib模块

def getWebPage(url):
wp = urllib.urlopen(url)
content = wp.read()
return content


[b]2.对抓取到的网页内容进行分析,提取有用URL
[/b]抓到的数据是用str存储的,下面使用python里的re.split()和re.match()

def analysisPage(content):
strlist = re.split('\"',content)
urlset = set([])
for str in strlist:
if re.match('http://www.cnblogs.com(/|\w)+', str):
urlset.add(str + '\n')
return list(urlset)


园里关于python的html解析的文章很多,看的我眼花缭乱,这里就不一一列举了。

这里有个问题,我把match里的pattern改成 ’http://www.cnblogs.com(/|\w)+html$' 就

匹配不出结果了,不知道什么原因,哪位大神知道。

[b]3.多线程[/b]

主要用了一个urllist和一个urlset。

urlset用来存储已经访问过的网页url,urllist用来存储待访问的网页url

申请四个线程并行的对urllist的url进行页面抽取,提取页面url加入到urllist中

为了互斥使用urllist和urlset,引入了listlock和setlock两把锁

全部代码如下:

import re
import urllib
import threading

def getWebPage(url):
wp = urllib.urlopen(url)
content = wp.read()
return content

def analysisPage(content, urllist, urlset):
strlist = re.split('\"',content)
geturlset = set([])
for str in strlist:
if re.match('http://www.cnblogs.com/(/|\w)+', str):
geturlset.add(str + '\n')

setlock.acquire()
geturlset = geturlset - urlset
setlock.release()

listlock.acquire()
for url in list(geturlset):
urllist.append(url)
listlock.release()

class MyThread(threading.Thread):
def __init__(self, urllist, urlset):
threading.Thread.__init__(self)
self.urllist = urllist
self.urlset = urlset

def run(self):
while True:
listlock.acquire()
if self.urllist:
url = self.urllist.pop(0)
listlock.release()
else:
listlock.release()
break

setlock.acquire()
if len(self.urlset) >= 50:
setlock.release()
break
else:
if url in self.urlset:
setlock.release()
continue
else:
self.urlset.add(url)
setlock.release()
content = getWebPage(url)
analysisPage(content, self.urllist, self.urlset)

listlock = threading.RLock()
setlock = threading.RLock()

if __name__ == '__main__':
starturl = 'http://www.cnblogs.com/\n'
content = getWebPage(starturl)
#urlset存放已访问过的网页url
#urllist存放待访问的网页url
urlset = set([starturl])
urllist = []
analysisPage(content, urllist, urlset)
tlist = []
for i in range(4):
t = MyThread(urllist, urlset)
t.start()
tlist.append(t)
for t in tlist:
t.join()
f = open('url.txt', 'w')
f.writelines(list(urlset))
f.close()


当urlset集合的元素超过50时就停止,当这个数值较大时,socket会出问题,我也不知道什么原因,应该和网络有关。

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: