本文参考http://zoulc001.iteye.com/blog/1186996

广度优先算法介绍

  整个的广度优先爬虫过程就是从一系列的种子节点开始,把这些网页中的"子节点"(也就是超链接)提取出来,放入队列中依次进行抓取。被处理过的链接需要放 入一张表(通常称为Visited表)中。每次新处理一个链接之前,需要查看这个链接是否已经存在于Visited表中。如果存在,证明链接已经处理过, 跳过,不做处理,否则进行下一步处理。

  初始的URL地址是爬虫系统中提供的种子URL(一般在系统的配置文件中指定)。当解析这些种子URL所表示的网页时,会产生新的URL(比如从页面中的<a href= "http://www.admin.com "中提取出http://www.admin.com 这个链接)。然后,进行以下工作:

  1. 把解析出的链接和Visited表中的链接进行比较,若Visited表中不存在此链接,表示其未被访问过。
  2. 把链接放入TODO表中。
  3. 处理完毕后,再次从TODO表中取得一条链接,直接放入Visited表中。
  4. 针对这个链接所表示的网页,继续上述过程。如此循环往复。

广度优先遍历是爬虫中使用最广泛的一种爬虫策略,之所以使用广度优先搜索策略,主要原因有三点:

  • 重要的网页往往离种子比较近,例如我们打开新闻网站的时候往往是最热门的新闻,随着不断的深入冲浪,所看到的网页的重要性越来越低。
  • 万维网的实际深度最多能达到17层,但到达某个网页总存在一条很短的路径。而广度优先遍历会以最快的速度到达这个网页。
  • 广度优先有利于多爬虫的合作抓取,多爬虫合作通常先抓取站内链接,抓取的封闭性很强。

广度优先遍历爬虫的python实现

 #encoding=utf-8
from bs4 import BeautifulSoup
import socket
import urllib2
import re
import zlib class MyCrawler:
def __init__(self,seeds):
#初始化当前抓取的深度
self.current_deepth = 1
#使用种子初始化url队列
self.linkQuence=linkQuence()
if isinstance(seeds,str):
self.linkQuence.addUnvisitedUrl(seeds)
if isinstance(seeds,list):
for i in seeds:
self.linkQuence.addUnvisitedUrl(i)
print "Add the seeds url \"%s\" to the unvisited url list"%str(self.linkQuence.unVisited)
#抓取过程主函数
def crawling(self,seeds,crawl_deepth):
#循环条件:抓取深度不超过crawl_deepth
while self.current_deepth <= crawl_deepth:
#循环条件:待抓取的链接不空
while not self.linkQuence.unVisitedUrlsEnmpy():
#队头url出队列
visitUrl=self.linkQuence.unVisitedUrlDeQuence()
print "Pop out one url \"%s\" from unvisited url list"%visitUrl
if visitUrl is None or visitUrl=="":
continue
#获取超链接
links=self.getHyperLinks(visitUrl)
print "Get %d new links"%len(links)
#将url放入已访问的url中
self.linkQuence.addVisitedUrl(visitUrl)
print "Visited url count: "+str(self.linkQuence.getVisitedUrlCount())
print "Visited deepth: "+str(self.current_deepth)
#未访问的url入列
for link in links:
self.linkQuence.addUnvisitedUrl(link)
print "%d unvisited links:"%len(self.linkQuence.getUnvisitedUrl())
self.current_deepth += 1 #获取源码中得超链接
def getHyperLinks(self,url):
links=[]
data=self.getPageSource(url)
if data[0]=="":
soup=BeautifulSoup(data[1])
a=soup.findAll("a",{"href":re.compile('^http|^/')})
for i in a:
if i["href"].find("http://")!=-1:
links.append(i["href"])
return links #获取网页源码
def getPageSource(self,url,timeout=100,coding=None):
try:
socket.setdefaulttimeout(timeout)
req = urllib2.Request(url)
req.add_header('User-agent', 'Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)')
response = urllib2.urlopen(req)
page = ''
if response.headers.get('Content-Encoding') == 'gzip':
page = zlib.decompress(page, 16+zlib.MAX_WBITS) if coding is None:
coding= response.headers.getparam("charset")
  #如果获取的网站编码为None
if coding is None:
page=response.read()
  #获取网站编码并转化为utf-8
else:
page=response.read()
page=page.decode(coding).encode('utf-8')
return ["",page]
except Exception,e:
print str(e)
return [str(e),None] class linkQuence:
def __init__(self):
#已访问的url集合
self.visted=[]
#待访问的url集合
self.unVisited=[]
#获取访问过的url队列
def getVisitedUrl(self):
return self.visted
#获取未访问的url队列
def getUnvisitedUrl(self):
return self.unVisited
#添加到访问过得url队列中
def addVisitedUrl(self,url):
self.visted.append(url)
#移除访问过得url
def removeVisitedUrl(self,url):
self.visted.remove(url)
#未访问过得url出队列
def unVisitedUrlDeQuence(self):
try:
return self.unVisited.pop()
except:
return None
#保证每个url只被访问一次
def addUnvisitedUrl(self,url):
if url!="" and url not in self.visted and url not in self.unVisited:
self.unVisited.insert(0,url)
#获得已访问的url数目
def getVisitedUrlCount(self):
return len(self.visted)
#获得未访问的url数目
def getUnvistedUrlCount(self):
return len(self.unVisited)
#判断未访问的url队列是否为空
def unVisitedUrlsEnmpy(self):
return len(self.unVisited)==0 def main(seeds,crawl_deepth):
craw=MyCrawler(seeds)
craw.crawling(seeds,crawl_deepth) if __name__=="__main__":
main(["http://www.baidu.com", "http://www.google.com.hk", "http://www.sina.com.cn"],10)

指定url和深度的广度优先算法爬虫的python实现的更多相关文章

  1. 【Python开发】【神经网络与深度学习】网络爬虫之python实现

    一.网络爬虫的定义 网络爬虫,即Web Spider,是一个很形象的名字. 把互联网比喻成一个蜘蛛网,那么Spider就是在网上爬来爬去的蜘蛛. 网络蜘蛛是通过网页的链接地址来寻找网页的. 从网站某一 ...

  2. Python|一文简单看懂 深度&广度 优先算法

    一.前言 以后尽量每天更新一篇,也是自己的一个学习打卡!加油!今天给大家分享的是,Python里深度/广度优先算法介绍及实现. 二.深度.广度优先算法简介 1. 深度优先搜索(DepthFirstSe ...

  3. 实验:用Unity抓取指定url网页中的所有图片并下载保存

    突发奇想,觉得有时保存网页上的资源非常麻烦,有没有办法输入一个网址就批量抓取对应资源的办法呢. 需要思考的问题: 1.如何得到网页url的html源码呢? 2.如何在浩瀚如海的html中匹配出需要的资 ...

  4. 双目深度估计传统算法流程及OpenCV的编译注意事项

    起因: 1. 双目立体视觉中双目深度估计是非常重要且基础的部分,而传统的立体视觉的算法基本上都在opencv中有相对优秀的实现.同时考虑了性能和效率.因此,学习使用opencv接口是非常重要的. 2. ...

  5. javascript怎么获取指定url网页中的内容

    javascript怎么获取指定url网页中的内容 一.总结 一句话总结:推荐jquery中ajax,简单方便. 1.js能跨域操作么? javascript出于安全机制不允许跨域操作的. 二.用ph ...

  6. 获取移除指定Url参数(原创)

    /// <summary> /// 移除指定的Url参数 /// 来自:http://www.cnblogs.com/cielwater /// </summary> /// ...

  7. 向指定URL发送GET方法获取资源,编码问题。 Rest风格

    http编码.今天遇到获取网页上的数据,用HTTP的GET请求访问url获取资源,网上有相应的方法.以前一直不知道什么事rest风格,现在我想就是开一个Controller,然后使人可以调用你的后台代 ...

  8. 用PHP实现URL转换短网址的算法示例

    短网址就是把一个长的地址转换在超级短的网址,然后访问短网址即可跳转到长网址了,下面来看用PHP实现URL转换短网址的算法与例子. 短网址(Short URL) ,顾名思义就是在形式上比较短的网址.在W ...

  9. 【转】js onclick用法:跳转到指定URL

    使用onclick跳转到其他页面/跳转到指定url   ☆如果是本页显示可以直接用location,方法如下: ①onclick="javascript:window.location.hr ...

随机推荐

  1. BFS、双向BFS和A*

    BFS.双向BFS和A* Table of Contents 1. BFS 2. 双向BFS 3. A*算法 光说不练是无用的.我们从广为人知的POJ 2243这道题谈起:题目大意:给定一个起点和一个 ...

  2. 10分钟学会Linux

    10分钟学会Linux有点夸张,可是能够让一个新手初步熟悉Linux中最重要最主要的知识,本文翻译的英文网页在众多Linux入门学习的资料中还是很不错的. 英文地址:http://freeengine ...

  3. uva10718 - Bit Mask(贪心)

    题目:uva10718 - Bit Mask(贪心) 题目大意:给出32位无符号的整数n ,给定边界L和R,要求在这个边界里面找出一个整数,它和N做或运算得到的值最大. 解题思路:要求做或运算得到的值 ...

  4. SharePoint 创建一个简单的Web Part 部分

    SharePoint 创建一个简单的Web Part 部分 标准Web零件有时会很强大,运行多个功能的能力. 本文介绍了如何使用Visual Studio 创建一个简单的Web部分. 1. 打开VS, ...

  5. 【百度地图API】如何使用suggestion--下拉列表方式的搜索建议

    原文:[百度地图API]如何使用suggestion--下拉列表方式的搜索建议 摘要: 百度地图上有一个很强大的搜索建议功能,以下拉列表的方式展示出来.比如,输入“百度”,下拉列表中就会出现“北京市海 ...

  6. 下载的youtube视频

    youtube 视频下载方法[详解]   1.打开网址: http://kej.tw/flvretriever/. 2.输入要下载的youtube视频的网址. 3.点击右侧RETRIEVE NOW ! ...

  7. php中utf8 与utf-8

    原文:php中utf8 与utf-8 相信很多程序员刚开始也会有这样的疑惑,如题,我也是.    其实,他们可以这样来区分.    一.在php和html中设置编码,请尽量统一写成“UTF-8”,这才 ...

  8. 分布式基础学习(2)分布式计算系统(Map/Reduce)

    二. 分布式计算(Map/Reduce) 分 布式式计算,同样是一个宽泛的概念,在这里,它狭义的指代,按Google Map/Reduce框架所设计的分布式框架.在Hadoop中,分布式文件 系统,很 ...

  9. Kindle使用技巧

    Kindle使用技巧 使用kindle也有几年了,但是好多kindle的使用技巧还不知道,在网上看到了一些,整理了一下. 1. 格式转换 把PDF发送到Kindle的时候,邮件主题写convert,这 ...

  10. 间支付系统,DataGridView

    我们通常看到很多的学习使用控制数据库和接口连接--DataGridView,在我们的房间,当我们敲开使用第一遍阶段似该控件--MSHFlexGrid,随着学习的深入,发现我们用到的平台越来越人性化了, ...