爬虫基本框架(单机版)伪代码,本质是一个多叉树层次遍历算法,图的广度优先搜索:
import Queue
#设置初始网页,树根
initial_page = "http://www.badtom.cn"
#新建待爬队列,已爬集合
url_queue = Queue.Queue()
seen = set()
#初始化待爬队列,已爬集合
seen.insert(initial_page)
url_queue.put(initial_page)
#待爬队列不为空
while(url_queue.size()>0):
current_url = url_queue.get() #取出待爬队例中第一个的url
store(current_url) #把这个url代表的网页存储好
for next_url in extract_urls(current_url): #提取这个url里链接的其他url
if next_url not in seen: #去重
seen.put(next_url) #更新已爬集合
url_queue.put(next_url) #更新待爬队列
爬虫基本框架(分布式)伪代码,主节点负责维护待爬队列和已爬集合,从节点负责处理页面,提取待爬链接:
#主节点master.py
#新建待爬队列,去重结构bf
distributed_queue = DistributedQueue()
bf = BloomFilter()
#待爬队列加入初始页面
initial_page = "www.badtom.cn"
distributed_queue.put(initial_page)
#server用于监听从节点发送的请求,并处理返回
server = RPCServer()
server.listen()
#server处理request请求
while(true):
request = server.request() #接收从节点发送的请求,没有则阻塞
if request.head == 'GET': #从节点请求任务
if distributed_queue.size() > 0:
page = distributed_queue.get() #从待爬队列取出列头
request.sendResponse(page) #发送给从节点
bf.put(page) #加入已爬集合
else:
send(null) #所有页面都已爬完,停止程序
break
elif request.head == 'POST': #从节点发送待爬回执
for next_url in request.urls
if next_url not in bf #不在已爬集合里的加入待爬队列
distributed_queue.put(request.url)
#从节点slave.py
#client用于向主节点发送请求
client = RPCClient()
#从主节点获取url任务,直到待爬队列为空程序停止
while((current_url = client.request_from_master('GET')) != null)
#处理当前页面
store(current_url)
#提取该页面所有链接
to_send = []
for next_url in extract_urls(current_url):
to_send.append(next_url)
#发送待爬链接给主节点
client.send_to_master('POST',to_send)