3

特定の URL に対応する Web ページを取得するための Python コードを作成し、そのページのすべてのリンクを解析してリンクのリポジトリに入れました。次に、作成したばかりのリポジトリからいずれかの URL のコンテンツをフェッチし、この新しいコンテンツからリポジトリへのリンクを解析し、停止するか、指定された数のリンクがフェッチされるまで、リポジトリ内のすべてのリンクに対してこのプロセスを続けます。

ここにコード:

import BeautifulSoup
import urllib2
import itertools
import random


class Crawler(object):
"""docstring for Crawler"""

def __init__(self):

    self.soup = None                                        # Beautiful Soup object
    self.current_page   = "http://www.python.org/"          # Current page's address
    self.links          = set()                             # Queue with every links fetched
    self.visited_links  = set()

    self.counter = 0 # Simple counter for debug purpose

def open(self):

    # Open url
    print self.counter , ":", self.current_page
    res = urllib2.urlopen(self.current_page)
    html_code = res.read()
    self.visited_links.add(self.current_page) 

    # Fetch every links
    self.soup = BeautifulSoup.BeautifulSoup(html_code)

    page_links = []
    try :
        page_links = itertools.ifilter(  # Only deal with absolute links 
                                        lambda href: 'http://' in href,
                                            ( a.get('href') for a in self.soup.findAll('a') )  )
    except Exception: # Magnificent exception handling
        pass



    # Update links 
    self.links = self.links.union( set(page_links) ) 



    # Choose a random url from non-visited set
    self.current_page = random.sample( self.links.difference(self.visited_links),1)[0]
    self.counter+=1


def run(self):

    # Crawl 3 webpages (or stop if all url has been fetched)
    while len(self.visited_links) < 3 or (self.visited_links == self.links):
        self.open()

    for link in self.links:
        print link



if __name__ == '__main__':

C = Crawler()
C.run()

このコードは内部リンクを取得しません (絶対形式のハイパーリンクのみ)

「/」または「#」または「.」で始まる内部リンクを取得する方法

4

2 に答える 2

7

さて、あなたのコードの種類は、何が起こっているかをすでに示しています。ラムダでは、http:// で始まる絶対リンクのみを取得しています (これは https FWIW を取得していません)。すべてのリンクを取得し、それらが http+ で始まっているかどうかを確認する必要があります。そうでない場合、それらは相対リンクであり、それが何であるかを知っているので、current_pageそれを使用して絶対リンクを作成できます。

これがコードの変更です。私のPythonは少し錆びているので申し訳ありませんが、実行したところ、Python 2.7で動作しました。それをクリーンアップして、エッジ/エラー検出を追加する必要がありますが、要点は次のとおりです。

#!/usr/bin/python

from bs4 import BeautifulSoup
import urllib2
import itertools
import random
import urlparse


class Crawler(object):
"""docstring for Crawler"""

def __init__(self):
    self.soup = None                                        # Beautiful Soup object
    self.current_page   = "http://www.python.org/"          # Current page's address
    self.links          = set()                             # Queue with every links fetched
    self.visited_links  = set()

    self.counter = 0 # Simple counter for debug purpose

def open(self):

    # Open url
    print self.counter , ":", self.current_page
    res = urllib2.urlopen(self.current_page)
    html_code = res.read()
    self.visited_links.add(self.current_page)

    # Fetch every links
    self.soup = BeautifulSoup(html_code)

    page_links = []
    try :
        for link in [h.get('href') for h in self.soup.find_all('a')]:
            print "Found link: '" + link + "'"
            if link.startswith('http'):
                page_links.append(link)
                print "Adding link" + link + "\n"
            elif link.startswith('/'):
                parts = urlparse.urlparse(self.current_page)
                page_links.append(parts.scheme + '://' + parts.netloc + link)
                print "Adding link " + parts.scheme + '://' + parts.netloc + link + "\n"
            else:
                page_links.append(self.current_page+link)
                print "Adding link " + self.current_page+link + "\n"

    except Exception, ex: # Magnificent exception handling
        print ex

    # Update links 
    self.links = self.links.union( set(page_links) )

    # Choose a random url from non-visited set
    self.current_page = random.sample( self.links.difference(self.visited_links),1)[0]
    self.counter+=1

def run(self):

    # Crawl 3 webpages (or stop if all url has been fetched)
    while len(self.visited_links) < 3 or (self.visited_links == self.links):
        self.open()

    for link in self.links:
        print link

if __name__ == '__main__':
    C = Crawler()
    C.run()
于 2013-10-03T20:26:32.273 に答える