本文参考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. 各大oj题目分类(转)

    POJ题目分类 | POJ题目分类 | HDU题目分类 | ZOJ题目分类 | SOJ题目分类 | HOJ题目分类 | FOJ题目分类 | 模拟题: POJ1006POJ1008POJ1013POJ1 ...

  2. Ubuntu下怎样切换到ROOT登录

    原文:http://james23dier.iteye.com/blog/721246 近期一直在学习linux,选择ubuntu作为联系的操作系统.然后一直发现自己所创建的用户和root用户不是一个 ...

  3. 【转】细说Cookie

    阅读目录 开始 Cookie 概述 Cookie的写.读过程 使用Cookie保存复杂对象 Js中读写Cookie Cookie在Session中的应用 Cookie在身份验证中的应用 Cookie的 ...

  4. linux_java_redis_postgresql_常用命令

     redis 常用语法telnet 192.168.18.210 6379keys *llen队列名称llen 队列名称 postgresql常用语法psql -h192.168.18.210 -Up ...

  5. python_基础学习_03_正则替换文本(re.sub)

    python的正则表达式模块是re,替换相关的方法是sub. 例如我们要做如下的替换将所有的 替换为空格,可以通过下面代码实现: import re input = 'hello world' #第一 ...

  6. MVC 接受Flash上传图片

    /// <summary> /// 经Flash上传图片 /// </summary> /// <param name="uid"></p ...

  7. jquery 直接调用 wcf,面向服务的SOA架构 ( 第二天)

    在前面的基础上,我们来开始第二天编写 客户端 的东西,不过讲之前,我想告诉大家的是: 这个简单的SOA的架构,我们直接通过wcf 调用到 后台的方法, 而中间没有使用 C#代码,大大减少我们客户端的代 ...

  8. 【百度地图API】如何制作多途经点的线路导航——驾车篇

    原文:[百度地图API]如何制作多途经点的线路导航--驾车篇 摘要: 休假结束,酸奶小妹要从重庆驾车去北京.可是途中要去西安奶奶家拿牛奶饼干呢!用百度地图API,能不能帮我实现这个愿望呢? ----- ...

  9. C#中实现WebBrowser控件的HTML源代码读写

    原文:C#中实现WebBrowser控件的HTML源代码读写 C#中实现WebBrowser控件的HTML源代码读写http://www.blogcn.com/user8/flier_lu/index ...

  10. POJ 2255 Tree Recovery 二叉树恢复

    一道和Leetcode的一道题目基本上一样的题目. 给出前序遍历和中序遍历序列,要求依据这些信息恢复一颗二叉树的原貌,然后按后序遍历序列输出. Leetcode上有给出后序和中序,恢复二叉树的. 只是 ...