2011-07-20 11 views
0

私はウェブサイトをクロールし、各ページからリンクを取得する動的な方法を探しています。私はBeauitfulsoupを試してみることにしました。 2つの質問:リンクを検索する入れ子のwhile文を使用して、これをより動的に行うにはどうすればよいですか。私はこのサイトからすべてのリンクを取得したい。しかし、入れ子のwhileループを引き続き入れたいとは思いません。pythonを使ってウェブサイトをクロールする

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 

私の2番目の質問は、私がサイトからすべてのリンクを取得したかどうかを知るためにとにかくあります。私を許してください、私はPython(1年かそれ以上)にいくぶん新しく、私はいくつかのプロセスとロジックが幼稚であるかもしれないことを知っています。しかし、何とか学ばなければならない。主に私はちょうどこれをより動的に入れ子にしたwhileループを使ってやりたいと思っています。あらゆる洞察力に感謝します。

+1

なぜドンすべてのリンクのアキュムレータとして1つの配列を使用して、それからサイトの詳細を見つけるときにそれらをキューに入れるだけですか? –

+0

よかったです。どのように私はより多くを見つけることを続けますか。上記のコードは、ページツリー内の3つのレベルだけ下に移動します。私はこれをより動的にして入れ子にしたいときにループを入れたいです。 – hackthisjay

+1

あなたは入れ子にする必要はありません。ページのhtmlを一度実行し、すべてのリンクの配列を持ちます。次のリンクに進みます。その場合、なぜ再帰関数を使用しないのですか?最終的にはスタックがオーバーフローしますが、Webは大きくなります:O –

答えて

4

ウェブサイトをスパイダリングしてすべてのリンクを取得するという問題はよくある問題です。 Googleが「spider web site python」を検索すると、これを行うライブラリを見つけることができます。ここでは一つだ私が見つかりました:

http://pypi.python.org/pypi/spider.py/0.5

はさらに良いことに、Googleはこの質問が既に尋ねたとStackOverflowの上ここに答えた:

Anyone know of a good Python based web crawler that I could use?

+0

私は元々StackOverflowのその投稿を見て、BeautifulSoup + urllib2の使用を決めました。しかし、主な問題は、どのようにこれらの入れ子のwhileループをより動的にするかということです。私はspider.pyを見ていきます。ありがとうございました – hackthisjay

0

コメントから、あなたの質問に答えるために、ここでの例です(それはルビーにありますが、私は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と適応するのは難しいはずがありません。

+0

ルビーに問題はありません。私はWatirを使用するために少し勉強しなければなりませんでした – hackthisjay

0

1)Pythonでは、コンテナの要素を数えずにインデックスに使用します。それが私たちがしたいことなので、その要素を反復するだけです。

2)複数レベルのリンクを処理するために、再帰を使用できます。

def followAllLinks(self, from_where): 
    for link in list(self.getAllUniqueLinks(from_where)): 
     self.followAllLinks(link) 

これはリンクのサイクルを処理しませんが、元のアプローチではありませんでした。既に訪問したリンクのsetを作成することでそれを処理できます。

+0

あなたが提出したこのメソッドを使用して既に訪問済みのリンクを構築するにはどうすればいいですか?これは正しい道のりです。本当にありがとう – hackthisjay

0

使用scrapy

Scrapyは、ウェブサイトをクロールし、 自分のページから構造化データを抽出するために使用 枠組みをクロールし、高速、高レベルの画面スクレイピングやWeb、です。データ 採掘からモニタリングおよび自動テストまで幅広い用途に使用できます。

2

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コードを取得するトップレベルのインスタンスがあります...

関連する問題