[英]Use python to crawl a website
所以我正在尋找一種動態的方式來抓取網站並從每個頁面中獲取鏈接。 我決定嘗試 Beauitfulsoup。 兩個問題:如何更動態地執行此操作,然后使用嵌套的 while 語句搜索鏈接。 我想從該站點獲取所有鏈接。 但我不想繼續放置嵌套的while循環。
topLevelLinks = self.getAllUniqueLinks(baseUrl)
listOfLinks = list(topLevelLinks)
length = len(listOfLinks)
count = 0
while(count < length):
twoLevelLinks = self.getAllUniqueLinks(listOfLinks[count])
twoListOfLinks = list(twoLevelLinks)
twoCount = 0
twoLength = len(twoListOfLinks)
for twoLinks in twoListOfLinks:
listOfLinks.append(twoLinks)
count = count + 1
while(twoCount < twoLength):
threeLevelLinks = self.getAllUniqueLinks(twoListOfLinks[twoCount])
threeListOfLinks = list(threeLevelLinks)
for threeLinks in threeListOfLinks:
listOfLinks.append(threeLinks)
twoCount = twoCount +1
print '--------------------------------------------------------------------------------------'
#remove all duplicates
finalList = list(set(listOfLinks))
print finalList
無論如何,我的第二個問題是要告訴我是否從該站點獲得了所有鏈接。 請原諒我,我對 python (一年左右)有點陌生,我知道我的一些流程和邏輯可能很幼稚。 但我必須以某種方式學習。 主要是我只想更動態地執行此操作,然后使用嵌套的 while 循環。 提前感謝您的任何見解。
爬取 web 站點並獲取所有鏈接的問題是一個常見問題。 如果您在 Google 上搜索“spider web 站點 python”,您可以找到可以為您執行此操作的庫。 這是我找到的一個:
http://pypi.python.org/pypi/spider.py/0.5
更好的是,谷歌發現這個問題已經在 StackOverflow 上提出並回答了:
如果使用 BeautifulSoup,為什么不使用 findAll() 方法? 基本上,在我的爬蟲中,我這樣做:
self.soup = BeautifulSoup(HTMLcode)
for frm in self.soup.findAll(str('frame')):
try:
if not frm.has_key('src'):
continue
src = frm[str('src')]
#rest of URL processing here
except Exception, e:
print 'Parser <frame> tag error: ', str(e)
為框架標簽。 “img src”和“a href”標簽也是如此。 不過我喜歡這個話題——也許是我在這里出了問題……編輯:有一個頂級實例,它保存 URL 並稍后從每個鏈接中獲取 HTML 代碼……
要從評論中回答您的問題,這里有一個示例(在 ruby 中,但我不知道 python,它們足夠相似,您可以輕松理解):
#!/usr/bin/env ruby
require 'open-uri'
hyperlinks = []
visited = []
# add all the hyperlinks from a url to the array of urls
def get_hyperlinks url
links = []
begin
s = open(url).read
s.scan(/(href|src)\w*=\w*[\",\']\S+[\",\']/) do
link = $&.gsub(/((href|src)\w*=\w*[\",\']|[\",\'])/, '')
link = url + link if link[0] == '/'
# add to array if not already there
links << link if not links =~ /url/
end
rescue
puts 'Looks like we can\'t be here...'
end
links
end
print 'Enter a start URL: '
hyperlinks << gets.chomp
puts 'Off we go!'
count = 0
while true
break if hyperlinks.length == 0
link = hyperlinks.shift
next if visited.include? link
visited << link
puts "Connecting to #{link}..."
links = get_hyperlinks(link)
puts "Found #{links.length} links on #{link}..."
hyperlinks = links + hyperlinks
puts "Moving on with #{hyperlinks.length} links left...\n\n"
end
對 ruby 感到抱歉,但它是一種更好的語言:P 並且應該不難適應,或者,就像我說的,理解。
1)在Python中,我們不計算容器的元素,並使用它們來索引; 我們只是迭代它的元素,因為那是我們想要做的。
2)為了處理多層次的鏈接,我們可以使用遞歸。
def followAllLinks(self, from_where):
for link in list(self.getAllUniqueLinks(from_where)):
self.followAllLinks(link)
這不處理鏈接循環,但原始方法也沒有。 您可以像 go 那樣構建一set
已訪問過的鏈接來處理這個問題。
使用scrapy :
Scrapy是一個快速的高級屏幕抓取和web爬取框架,用於爬取網站並從其頁面中提取結構化數據。 它可用於廣泛的用途,從數據挖掘到監控和自動化測試。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.