1. 現在のシステムを微調整する
- ページの処理が完了するまでページのステータスを 1 に設定するのを延期する場合、ワーカーは早期に「ジョブ完了」を宣言すべきではありません。
- ステップ 2 は、クロールを開始する最初のページにのみ必要です。
したがって、システムは次のようになります。
start job:
1. Create a page record in the database. Set status=0. Add page to queue.
worker:
1. Get the next page from the queue.
2. Download the page contents and process. Might take up to a minute or so.
3. For each link in the page
1. Check if the link is already registered in the database.
2. If not, create a new page record. Set status=0 and add the link to the queue.
4. After the for loop ends, set status=1 for this page.
5. Check whether the count of pages with status=0 is 0. If yes, the job is done.
前の Web クローリング ジョブが終了する前に次の Web クローリング ジョブが開始された場合、最後の Web クローリング ジョブの最後にのみ「ジョブが完了」するという問題があります。おそらく、ジョブ ID をデータベース ページ レコードに追加して、「完了したジョブ」を次のように再定義できます。count(status=0 and job-id=x) = 0
2.RQのジョブクラスを活用する
RQ ドキュメントから:
ジョブがキューに入れられると、 queue.enqueue() メソッドは Job インスタンスを返します。...ジョブがまだ終了していない場合はNoneを返し、ジョブが終了した場合はNone以外の値を返す便利な結果アクセサープロパティがあります(もちろん、ジョブに最初の戻り値があると仮定します) .
2 つの異なるタイプのジョブをキューに入れることができます。1 つは「Web ページの取得」で、もう 1 つはクロール プロセスを管理するためのものです。
管理ジョブは、すべての「Web ページのフェッチ」ジョブを開始して追跡します。すべてのサブジョブが完了したため、いつ「ジョブが完了した」かがわかります。
クロール プロセスを管理するために、必ずしもデータベースに何かを書き込む必要はありません。
おそらく別々のキューで同時に作業できるようにcrawl
、 2 つ以上のワーカーを実行する必要があります。fetch
def something_web_facing():
...
queue.enqueue(crawl, 'http://url.com/start_point.html')
...
def crawl(start_url):
fetch_jobs = []
seen_urls = set()
seen_urls.add(start_url)
fetch_jobs.append( queue.enqueue(fetch, start_url) )
while len(fetch_jobs) > 0:
# loop over a copy of fetch_jobs
for job in list(fetch_jobs):
# has this job completed yet?
if job.result:
# a fetch job returns a list of the next urls to crawl
for url in job.result:
# fetch this url if we haven't seen it before
if url not in seen_urls:
seen_urls.add(url)
fetch_jobs.append( queue.enqueue(fetch, url) )
fetch_jobs.remove(job)
time.sleep(1)
return "Job done!"
def fetch(url):
"""Get web page from url, return a list of links to follow next"""
html_page = download_web_page(url)
links_to_follow = find_links_to_follow(html_page)
return links_to_follow
3. 他人の Web クローラー コードを使用する
スクレイピー
スクレイピーを使用するジョブをキューに入れることができます。スクリプトからスクレイピーを実行する