本文参考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. DFS-hdu-2821-Pusher

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=2821 题目意思: 给一个n*n的矩阵,里面有些位置是空的,有些位置有箱子(a代表一个箱子,b代表两个 ...

  2. [转载]Arguments

    一.Arguments 该对象代表正在执行的函数和调用他的函数的参数. [function.]arguments[n] 参数function :选项.当前正在执行的 Function 对象的名字. n ...

  3. SDUT 1124-飞跃荒野(三维BFS)

    飞跃原野 Time Limit: 5000ms   Memory limit: 65536K  有疑问?点这里^_^ 题目描写叙述 勇敢的法里奥出色的完毕了任务之后.正在迅速地向自己的基地撤退.但因为 ...

  4. iWatch # 初始化工程

    iWatch --利用swift,开发iWatch手表小应用! 远程仓库,团队开发: $ git init $ git add . $ git commit -m “ProjectName” // p ...

  5. CSS hack 如何区分所有IE浏览器和非IE浏览器

    网上方法很多,例如,测试后得出以下结论,多余的话不说了,直入主题: 1.所有的推理IE浏览器 正解:此写法仅仅被lE浏览器识别,非IE浏览器不识别. <!--[if IE]> <st ...

  6. Swift语言指南(二)--语言基础之注释和分号

    原文:Swift语言指南(二)--语言基础之注释和分号 注释 通过注释向自己的代码中注入不可执行的文本,作为你自己的笔记或提示.Swift编译器运行时会忽略注释. Swift的注释与C语言极其相似,单 ...

  7. 在线预览Excel

    遇到的问题各种多 <system.web>        <identity impersonate="true" userName="Administ ...

  8. checkbox属性checked="checked"但状态不是勾选状态的解决办法

    原因: jQuery API明确说明,1.6+的jQuery要用prop,不能用attr否则无效,尤其是checkBox的checked的属性的判断.

  9. ASP.NET MVC3中Model验证

    原文:ASP.NET MVC3中Model验证 概述 上节我们学习了Model的数据在界面之间的传递,但是很多时候,我们在数据传递的时候为了确保数据的有效性,不得不给Model的相关属性做基本的数据验 ...

  10. 高德地图教程_poi搜索和显示

    通过高仿深圳的应用近期打算.UI我们已经做了,我见过APP查询界面.关闭网络也将是能够查询其指示数据被存储在数据库中,或者是第一网络,所有网站上的数据是好了.我想简单地使用查询地图提供了. 曾经是接触 ...