1

私は、お気に入りの音楽ブログから MP3 をクロールして収集し、後で聴くための個人 Web サイトを持っています...

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

スクリプトはページの 2 レベル下までしかクロールしないため、メイン ページ www.url.com とそのページ上のリンク www.url.com/post1 www.url.com/post2

私の問題は、より多くのブログのコレクションを取得し始めたことです。スキャンされるのは 20 ~ 30 分に 1 回だけです。新しいブログをスクリプトに追加すると、毎分 1 つしか処理されないため、リンクのスキャンにバックアップがあります。

PHP の仕組みにより、スクリプトの実行時間のために、スクリプトが複数のリンクまたは限られた量のリンクを処理することを許可できないようです。メモリ制限。タイムアウトなど

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

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

DB に影響を与える複数のスクリプトを作成して、相互に上書きせずに結果をキューに入れる方法はありますか?

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

何か案は?

ありがとう。

4

5 に答える 5

2

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

start_a_scan(){
    //Start mysql transaction (needs InnoDB afaik)        
    BEGIN 
        //Get first entry that has timed out and is not being scanned by someone
        //(And acquire an exclusive lock on affected rows)
        $row = SELECT * FROM scan_targets WHERE being_scanned = false AND \
                (scanned_at + 60) < (NOW()+0) ORDER BY scanned_at ASC \
                      LIMIT 1 FOR UPDATE
        //let everyone know we're scanning this one, so they'll keep out
        UPDATE scan_targets SET being_scanned = true WHERE id = $row['id']
    //Commit transaction
    COMMIT
    //scan
    scan_target($row['url'])
    //update entry state to allow it to be scanned in the future again
    UPDATE scan_targets SET being_scanned = false, \
              scanned_at = NOW() WHERE id = $row['id']
}

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

そして、複数のスキャン プロセスを並行して実行できます。ええ!

乾杯!

編集: FOR UPDATE で最初の SELECT を作成する必要があることを忘れていました。詳細はこちら

于 2009-06-08T18:43:04.877 に答える
2

カールマルチを使おう!

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

http://us3.php.net/curl

ほとんどの場合、Web サイトで待機しているときに、db の挿入と html の解析が桁違いに高速になります。

スクレイピングしたいブログのリストを作成し、curl multi に送信します。待機してから、すべての呼び出しの結果を順次処理します。その後、次のレベルダウンで2回目のパスを実行できます

http://www.developertutorials.com/blog/php/parallel-web-scraping-in-php-curl-multi-functions-375/

于 2009-06-08T19:17:36.913 に答える
1

PHP の仕組みにより、スクリプトの実行時間のために、スクリプトが複数のリンクまたは限られた量のリンクを処理することを許可できないようです。メモリ制限。タイムアウトなど

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

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

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

于 2009-06-08T18:20:06.883 に答える