私は現在、複数の CPU コアを利用するための Python での Web クローラーの開発に取り組んでいます。これはマルチプロセッシングへの私の最初の試みであり、実装と概念の両方でいくつかの問題に遭遇しています。これまでのところ、開発のために、Web サイトをクロールして必要なコンテンツを取得するプロセスを 1 つ生成しているだけですが、これは問題ではありません。
私の問題は、子によって解析された URL をページからキューに送り返し、すべての子プロセスがこのキューにアクセスしてより多くの作業を取得できるようにするときに始まります。
これにより、このプログラムを複数のプロセスで開始し、それらを継続的に取得/実行し、完了したら join() を実行する方法がわかりません。URL の数は明らかに多く、不明な数であるため、終了までに何を行うかを設定することはできません。
私は新進の Python 開発者であるため、あらゆる批評や批判を歓迎します。また、これはかなり複雑な質問であることも承知しており、コミュニティの助けに大いに感謝しています!
既存の Web クローラーを使用するように提案しないでください。これは私にとって何よりも学習経験であるため、既存のソフトウェアを使用してクロールすることは役に立ちません。
以下は、私が持っているものと私が理解していることのアイデアを提供するためのこれまでのコードです。
import multiprocessing as mp
import re
import subprocess
import time
from bs4 import BeautifulSoup as bs4
import requests
class CrawlParseProcess(mp.Process):
def __init__(self, url):
mp.Process.__init__(self)
# This implies that a new process per URL which is not smart.
# Instead should the link queue be passed or something?
self.url = url
def run(self):
proc_name = self.name
response = requests.get(self.url)
links = self.link_parse(response.text, self.url)
def link_parse(self, html, url):
soup = bs4(html)
for link in soup.find_all('a'):
if link.has_attr('href'):
link = link.get('href')
if str(link).startswith('http') and 'example.com' in link:
print link
pattern = re.compile('http://www.example.com/.+\d/*')
if pattern.search(url):
return_obj = self.parse(html)
return_obj["date"] = time.time()
def parse(self, html):
soup = bs4(html)
return_obj = {
"url" : self.url,
"title" : soup.find('h1', {'itemprop' : 'name'}).text,
"date-added" : soup.find('div', {'class' : 'addedwhen clrfix'}).text,
"p" : soup.find('p', {'class' : 'time1'}).text,
"c" : soup.find('p', {'class' : 'time2'}).text,
"t" : soup.find('h3', {'class' : 'duration'}).text,
"items" : soup.find_all('li', {'itemprop' : 'items'}),
}
return return_obj
if __name__ == '__main__':
p = CrawlParseProcess("www.example.com")
p.start()
p.join()