免責事項この質問に直接答えるのは難しく、答えるにはスクレイピーとプログラムの順序付けについてよく理解している必要があります。質問を直接答えやすいものに縮小するのは難しいです。
私の知る限り、アイテム パイプライン ハンドラからリクエストを返すことはできません。フォーラムから特定のカテゴリのすべての投稿を解析しようとしています。フォーラムを横断する私の戦略は次のとおりです。
- カテゴリ内のすべてのページのリストを作成し、それらをダウンローダーに送信して取得します。
- 各ページ内のすべてのトピックを取得し、アイテム パイプラインに送信します。
- すべてのページ アイテムが処理される (リレーショナル データベースに挿入される) のを待ってから、すべてのトピックのトラバースを開始します。
ステップ 3 をシーケンスする方法がわかりません。シーケンス ロジックを支援するために、次の 2 つのオブジェクト (最後にリストされています) を使用しています。category::process_page
トピック ページをトラバースする際に使用されるリクエスト ハンドラです。
カテゴリ クラス :
フェーズ 1 の終了は、すべてのトピック ページが受信されたことを表します。フェーズ 2 の終了は、アイテム パイプラインがすべてのトピックの基礎作業を処理したことを意味します。
特定のトピック リスト ページ内のすべてのトピックを表すトピック クラス。フェーズ 1 の終了は、ページ内のすべてのトピックがデータベースに送信されたことを意味します。ページ内の各トピックがデータベースに追加されると、そのページはカテゴリから削除されます。すべてのページが完了すると、クローラーはすべてのトピックのダウンロードに移ります。
では、アイテム パイプラインで実行されるロジックを介して、カテゴリ フェーズ 2 が終了するのを待つことができるように、ダウンローダをブロックするにはどうすればよいでしょうか? これのためにスクレイピーにいくつかの機械がありますか? おそらく、アイテム パイプライン内からダウンローダ ロジックを再起動できますか?
おそらくこれを行う方法はたくさんありますが、私はPythonとC ++ / Cシステムプログラマーが初めてです。
注:私の最初の設計は、3 ~ 4 個の異なるスパイダーで行う予定でした。1 つはフォーラム階層を取得し、2 番目はすべてのトピックをダウンロードし、3 番目はすべての投稿を取得し、4 番目は更新が必要なトピックをマークします。しかし、この問題にはもっと自然な解決策があるはずです。最後の 3 つのスパイダーを 1 つにまとめたいと思います。
スプーンは、bash に頼らずにスパイダーを起動するロジックを提供するという答えを受け入れます (GUI からスパイダーを駆動できると便利です)。それから、ドライバー プログラムを作成して、最初の設計に固執することができます。
###############################################################################
class TopicPageItemBundle:
def __init__(self,topic_page_url,category_item_bundle):
self.url = topic_page_url
self.topics = set()
self.topics_phase1 = set()
self.category_item_bundle = category_item_bundle
def add_topic(self, topic_url):
self.topics.add(topic_url)
self.topics_phase1.add(topic_url)
def topic_phase1_done(self, topic_url):
self.topics.remove(topic_url)
if len(self.topics_phase1) == 0:
return true
else:
return false
###############################################################################
class CategoryItemBundle:
def __init__(self,forum_id):
self.topic_pages = {}
self.topic_pages_phase1 = set()
self.forum_id = forum_id
def add_topic_page(self,topic_page_url):
tpib = TopicPageItemBundle(topic_page_url,self)
self.topic_pages[topic_page_url] = tpib
self.topic_pages_phase1.add(topic_page_url)
self.topic_pages_phase2.add(topic_page_url)
def process_page(self, response):
return_items = []
tp = TopicPage(response,self)
pagenav = tp.nav()
log.msg("received " + pagenav.make_nav_info(), log.INFO)
page_bundle = self.topic_pages[response.url]
posts = tp.extract_posts(self.forum_id)
for post in posts:
if post != None:
page_bundle.add_topic(post["url"])
post["page_topic_bundle"] = page_bundle
return return_items
# phase 1 represents finishing the retrieval of all topic pages in a forum
def topic_page_phase1_done(self, topic_page_url):
self.topic_pages_phase1.remove(topic_page_url)
if len(self.topic_pages_phase1) == 0:
return true
else:
return false
def topic_page_phase2_done(self,topic_page_url)
self.topic_pages_phase2.remove(topic_page_url)
if len(self.topic_pages_phase2) == 0:
return true
else:
return true
###############################################################################