2017-05-11 11 views
0

私が作成したクローラは、Webページから名前とURLを取得しています。今、次のページからデータを取得するために、next_pageによって生成されたリンクをクローラが使用するようにすることはできません。私はクラスを使ってクローラを作成するのがとても新しいです。なぜなら、私は自分の考えでさらに動くことができないからです。私はすでにコード内で少し歪曲していますが、何も結果をもたらさず、エラーもスローしません。誰かがそれを調べてくれることを願っています。次のページの生成リンクを再帰的にクロールすることはできません

import requests 
from lxml import html 

class wiseowl: 
    def __init__(self,start_url): 
     self.start_url=start_url 
     self.storage=[] 

    def crawl(self): 
     self.get_link(self.start_url) 

    def get_link(self,link): 
     url="http://www.wiseowl.co.uk" 
     response=requests.get(link) 
     tree=html.fromstring(response.text) 
     name=tree.xpath("//p[@class='woVideoListDefaultSeriesTitle']/a/text()") 
     urls=tree.xpath("//p[@class='woVideoListDefaultSeriesTitle']/a/@href") 
     docs=(name,urls) 
     self.storage.append(docs) 

     next_page=tree.xpath("//div[contains(concat(' ', @class, ' '), ' woPaging ')]//a[@class='woPagingItem']/@href") 
     for npage in next_page: 
      if npage is not None: 
       self.get_link(url+npage) 


    def __str__(self): 
     return "{}".format(self.storage) 


crawler=wiseowl("http://www.wiseowl.co.uk/videos/") 
crawler.crawl() 
for item in crawler.storage: 
    print(item) 

答えて

1

私はそれを試してみる、あなたのクラスのいくつかの部分を変更:

class wiseowl: 
    def __init__(self,start_url): 
     self.start_url=start_url 
     self.links = [ self.start_url ] # a list of links to crawl # 
     self.storage=[] 

    def crawl(self): 
     for link in self.links : # call get_link for every link in self.links # 
      self.get_link(link) 

    def get_link(self,link): 
     print('Crawling: ' + link) 
     url="http://www.wiseowl.co.uk" 
     response=requests.get(link) 
     tree=html.fromstring(response.text) 
     name=tree.xpath("//p[@class='woVideoListDefaultSeriesTitle']/a/text()") 
     urls=tree.xpath("//p[@class='woVideoListDefaultSeriesTitle']/a/@href") 
     docs=(name,urls) 
     #docs=(name, [url+u for u in urls]) # use this line if you want to join the urls # 
     self.storage.append(docs) 
     next_page=tree.xpath("//div[contains(concat(' ', @class, ' '), ' woPaging ')]//*[@class='woPagingItem' or @class='woPagingNext']/@href") # get links form 'woPagingItem' or 'woPagingNext' # 
     for npage in next_page: 
      if npage and url+npage not in self.links : # don't get the same link twice # 
       self.links += [ url+npage ] 

    def __str__(self): 
     return "{}".format(self.storage) 

crawler=wiseowl("http://www.wiseowl.co.uk/videos/") 
crawler.crawl() 
for item in crawler.storage: 
    item = zip(item[0], item[1]) 
    for i in item : 
     print('{:60} {}'.format(i[0], i[1])) # you can change 60 to the value you want # 
+0

あなたの答えはありがとうございました。試すものは何もありません。あなたが私の乱雑なコードに触れるたびに、それは今のように魔法のように動作します。私はここからもう一つ期待しています:最初の列のビデオタイトルとリンクが2番目の列にあるように、結果を2つの列に表示するにはどうすればいいですか?私は結果のコードがリストとして解析されていることを意味しました。それは私のせいだ。もう一度おねがいします。 – SIM

+1

forループを更新し、2つの列を出力します。リンクが完全なURLになるようにするには、 'get_link'の8行目のコメントを外すことができます –

+0

OMG !!!!!あなたがここでやったことは、私の期待をはるかに超えています。それはすべての問題を解決します。長い生きているt.m.adam !!!! – SIM

0

あなたは、両方の訪問済みリンク(無限ループを回避するため)だけでなく、あなたが訪問することは至っていないリンクのための容器を保持するためのデータ構造のいくつかのタイプを利用することを考えるべきです。本質的にクロールはインターネットの幅広い最初の検索です。基本アルゴリズムの理解を深めるため、Google検索の最初の検索を行う必要があります。

  1. 訪問する必要があるリンクのキューを実装します。リンクにアクセスするたびに、すべてのリンクのページをスクラップして、それぞれをエンキューします。
  2. エンキューしている各リンクが既に訪問されているかどうかを確認するために、Pythonまたは辞書のセットを実装します。訪問された場合は、エンキューしません。
  3. あなたのクローラ方法のようなものでなければなりません:

    def crawler(self): 
    while len(self.queue): 
    curr_link = self.queue.pop(0) 
    # process curr_link here -> scrape and add more links to queue 
    # mark curr_link as visited 
    
+0

ありがとうryankdwyerを、あなたの答えのために。実際、私はループに慣れています。私はどのように私のループの性質は、私はループになることができ、私はそれが期待するものを取得することができるようにメソッドに私の新しく作成されたリンクを推進するかと尋ねた私の記事で尋ねるつもりはなかった。 – SIM

関連する問題