1


0

後で聴くために、お気に入りの音楽ブログからクロールしてMP3を収集する個人的なWebサイトがあります。

それが機能する方法は、CRONジョブがDB内の次のブログをクロールする毎分1回.phpスクリプトを実行することです。 結果はDBに書き込まれ、次に2番目の.phpスクリプトが収集されたリンクをクロールします。

スクリプトは2つのレベルをページにクロールするだけなので、.. メインページwww.url.comとそのページ上のリンクwww.url.com/post1 www.url.com/post2

私の問題は、私がブログのより大きなコレクションを手に入れるようになったことです。 それらは20から30分に一度だけスキャンされます、そして私がスクリプトに新しいブログを追加するとき、1つだけが毎分処理されるのでリンクをスキャンすることにおけるバックアップがあります。

PHPの仕組みのおかげで、スクリプトの実行時間のせいで、スクリプトに複数のリンクや限られた量のリンクを処理させることはできません。 メモリ制限 タイムアウトなど

また、同じスクリプトの複数のインスタンスを実行することはできません。それらはDB内で互いに上書きされるためです。

このプロセスをスピードアップするための最善の方法は何ですか。

複数のスクリプトを使用してDBに影響を与えることができますが、それらが互いを上書きせずに結果をキューに入れないようにそれらを作成する方法はありますか?

スクリプトが独自のペースでリンクを処理できるようにPHPでスレッドを作成する方法はありますか?

何か案は?

ありがとう。

5 Answer


2


並列スキャナーを実行するための疑似コード:

start_a_scan(){// mysqlトランザクションを開始します(InnoDB afaikが必要です)BEGIN //タイムアウトし、誰かにスキャンされていない最初のエントリを取得しますWHERE being_scanned = false AND \(scans_at 60)<(NOW()0)order byスキャンASC ASC \ LIMIT 1 FOR UPDATE //これをスキャンしていることを全員に知らせます。 WHERE id = $ row ['id'] //トランザクションのコミットCOMMIT // scan scan_target($ row ['url'])//将来再びスキャンできるようにエントリの状態を更新するUPDATE scan_targets SET being_scanned = false、 \ scans_at = NOW()WHERE id = $ row ['id']}

中止されたスキャンも停止しているかどうかを定期的にチェックし、それらを再びスキャンできるように状態をリセットする「クリーナー」がおそらく必要です。

そして、いくつかのスキャンプロセスを並行して実行することができます。 そうだね。

乾杯!

EDIT:FOR UPDATEを使って最初のSELECTを作成する必要があることを忘れました。 もっと読むhttp://dev.mysql.com/doc/refman/5.1/en/innodb-locking-reads.html


2


CURL MULTIを使用してください。

Curl-mutliを使うと、ページを並行して処理できます。

あなたがウェブサイトで待っているほとんどの時間、db挿入とhtml解析をすることは桁違いに速いです。

あなたがスクレープしたいブログのリストを作成し、マルチをカールするためにそれらを送ります。 待ってから、すべての呼び出しの結果を順次処理します。 その後、次のレベルの2番目のパスを実行できます


1


これはきっとあなたの質問に対する答えではありませんが、もしあなたがpythonを勉強しても構わないのなら私はあなたのニーズを満たすべきである Scrap、オープンソースのWebクローラー/スクレーパーフレームワークを見ることを勧めます。 繰り返しますが、これはPHPではなくPythonです。 それはどのようにこれまで非常に分配可能などです…​ 私はそれを自分で使います。


1


_ PHPの仕組みのおかげで、スクリプトの実行時間のせいで、スクリプトに複数のリンクや限られた量のリンクを処理させることはできません。 メモリ制限 タイムアウトなど _

コードがメモリをリークした場合、メモリ制限は問題になります。 メモリ制限を上げるのではなく、これを修正する必要があります。 スクリプトの実行時間はセキュリティ対策です。cliスクリプトでは無効にすることができます。

_ また、同じスクリプトの複数のインスタンスを実行することはできません。それらはDB内で互いに上書きされるためです。 _

インスタンスが互いにオーバーライドしないようにアプリケーションを構築できます。 これを行う一般的な方法は、サイトごとに分割することです。例えば。 クロールするサイトごとに別々のスクリプトを起動します。


0


CLIスクリプトは、最大実行時間によって制限されません*。 一度に大量のデータをメモリに保存しない限り、メモリ制限は通常問題になりません。 タイムアウトはアプリケーションによって適切に処理される必要があります。

一度に複数のインスタンスを実行できるようにコードを変更することができます - だれかがさらにアドバイスするにはスクリプトを投稿する必要があります。 Peterが言うように、おそらくデザインを見る必要があります。 ペーストビンでコードを提供することは私達があなたを助けるのを助けるでしょう:)