深度優先遍歷的優點是設計簡單,但是這種遍歷的最大缺陷是:由於頂層文章價值最高,往下逐漸減弱。無限制的深度挖取,挖取的文章的價值不會太大。
廣度優先搜尋是爬蟲中使用最廣泛的一種策略,主要原因有以下三點:
(1)重要的網頁往往離種子比較近,例如我們開啟新聞**時首先看到的往往是最熱門的新聞,隨著不算的深入衝浪,所看到的的網頁(新聞)的重要性越來越低。
(2)全球資訊網的實際深度最多能達到17層,但到達某個網頁總存在一條很短的路徑。而廣度優先搜尋會以最快的速度到達這個網頁。
(3)廣度優先有利於多爬蟲的合作抓取,多爬蟲合作通常先抓取站內鏈結,抓取的封閉性很強。
from bs4 importbeautifulsoup
import
requests
importre#
自定義佇列類
class
linkquence:
def__init__
(self):
#已訪問的url集合
self.visted =
#待訪問的url集合
self.unvisited =
#獲取訪問過的url佇列
defgetvisitedurl(self):
return
self.visted
#獲取未訪問的url佇列
defgetunvisitedurl(self):
return
self.unvisited
#新增到訪問過得url佇列中
defaddvisitedurl(self, url):
#移除訪問過得url
defremovevisitedurl(self, url):
self.visted.remove(url)
#未訪問過得url出佇列
defunvisitedurldequence(self):
try:
return
self.unvisited.pop()
except
:
return
none
#保證每個url只被訪問一次
defaddunvisitedurl(self, url):
if url != ""
and url not
in self.visted and url not
inself.unvisited:
self.unvisited.insert(0, url)
#獲得已訪問的url數目
defgetvisitedurlcount(self):
return
len(self.visted)
#獲得未訪問的url數目
defgetunvistedurlcount(self):
return
len(self.unvisited)
#判斷未訪問的url佇列是否為空
defunvisitedurlsenmpy(self):
return len(self.unvisited) ==0
class
mycrawler:
def__init__
(self, seeds):
#初始化當前抓取的深度
self.current_deepth = 1
#使用種子初始化url佇列
self.linkquence =linkquence()
ifisinstance(seeds, str):
self.linkquence.addunvisitedurl(seeds)
ifisinstance(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))
#抓取過程主函式
defcrawling(self, seeds, crawl_deepth):
#迴圈條件:抓取深度不超過crawl_deepth
while self.current_deepth <=crawl_deepth:
#while
notself.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) #
獲取visiturl中的所有超連結
print("
get %d new links
" %len(links))
#將visiturl放入已訪問的url中
self.linkquence.addvisitedurl(visiturl)
print("
visited url count:
" +str(self.linkquence.getvisitedurlcount()))
print("
visited deepth:
" +str(self.current_deepth))
#未訪問的url入列 也就是visiturl網頁中的所有超連結links
for link in
links:
self.linkquence.addunvisitedurl(link)
print("
%d unvisited links:
" %len(self.linkquence.getunvisitedurl()))
self.current_deepth += 1
#獲取原始碼中得超連結
defgethyperlinks(self, url):
links =
data = self.getpagesource(url) #
獲取url網頁原始碼
#獲取網頁原始碼
defgetpagesource(self, url):
try:
r =requests.get(url)
r.raise_for_status()
r.encoding = '
utf-8
'return
r.text
except
:
return
''def
main(seeds, crawl_deepth):
craw =mycrawler(seeds)
craw.crawling(seeds, crawl_deepth)#if
__name__ == '
__main__':
main(
"", 3)
參考
深度優先搜尋與廣度優先搜尋
深度優先遍歷的主要思想就是 首先以乙個未被訪問過的頂點作為起始頂點,沿當前頂點的邊走到未訪問過的頂點 當沒有未訪問過的頂點時,則回到上乙個頂點,繼續試探訪問別的頂點,直到所有的頂點都被訪問。沿著某條路徑遍歷直到末端,然後回溯,再沿著另一條進行同樣的遍歷,直到所有的頂點都被訪問過為止。通過上面的圖例可...
廣度優先搜尋與深度優先搜尋
廣度優先搜尋使用的是步步為營的策略,每執行一步迴圈就會把所有可能的情況加入佇列,直到調出迴圈。適用於求最短的問題。深度優先搜尋則是依次遍歷每一種情況,直至找到問題的解。深度優先搜尋和廣度優先搜尋都屬於窮竭法。在執行記憶體空間上面,廣度優先搜尋與情況數成正比,而深度優先搜尋與遞迴深度成正比。inclu...
深度優先搜尋與廣度優先搜尋
首先我們以鍊錶的形式儲存乙個圖 struct edge vectorg2 maxvex int source 6 3 表示從頂點0到頂點1的邊的權值為10。以鄰接鍊錶形式生成該圖 void genedge 首先以乙個未被訪問過的頂點作為起始頂點,沿著當前頂點的邊走到未訪問過的頂點 當沒有未訪問過的頂...