1

MySQL テーブルに約 6,600 万のドメインがあり、すべてのドメインでクローラーを実行し、クローラーが完了したら行数 = 1 を更新する必要があります。

クローラー スクリプトは、php クローラー ライブラリを使用して php にあります。ここにスクリプトがあります。

set_time_limit(10000);
        try{

            $strWebURL          =   $_POST['url'];
            $crawler    =   new MyCrawler();
            $crawler->setURL($strWebURL);
            $crawler->addContentTypeReceiveRule("#text/html#");
            $crawler->addURLFilterRule("#\.(jpg|jpeg|gif|png)$# i");
            $crawler->enableCookieHandling(true);
            $crawler->setTrafficLimit(1000 * 1024);
            $crawler->setConnectionTimeout(10);

            //start of the table
            echo '<table border="1" style="margin-bottom:10px;width:100% !important;">';
            echo '<tr>';
            echo '<th>URL</th>';
            echo '<th>Status</th>';
            echo '<th>Size (bytes)</th>';
            echo '<th>Page</th>';
            echo '</tr>';
            $crawler->go();
            echo '</table>';

            $this->load->model('urls');
            $this->urls->incrementCount($_POST['id'],'urls');

        }catch(Exception $e){

        }

$this->urls->incrementCount(); 行のみを更新し、カウント列をマークする = 1

66M のドメインがあるため、サーバーで cronjob を実行する必要があり、cronjob はコマンド ラインで実行されるため、ヘッドレス ブラウザーが必要だったので、ヘッドレス ブラウザー (phantomjs) がないと動作するようにクローラーが動作しないため、phanjomjs を選択しました。

私が直面した最初の問題は、mysql dbからドメインをロードし、jsスクリプトからクローラースクリプトを実行することでした。

  • json 形式でドメインを返す php スクリプトを作成し、それを js ファイルからロードし、ドメインを foreach してクローラーを実行しましたが、うまく機能せず、しばらくすると動かなくなりました。
  • 次に試したのは、まだ使用している Python スクリプトを作成して、mysql db からドメインを直接ロードし、Python スクリプトから各ドメインでファントム js スクリプトを実行することです。

ここにコードがあります

import MySQLdb
import httplib
import sys
import subprocess
import json

args = sys.argv;

db = MySQLdb.connect("HOST","USER","PW","DB")
cursor = db.cursor()
#tablecount = args[1]
frm = args[1]
limit = args[2]

try:
    sql = "SELECT * FROM urls WHERE count = 0 LIMIT %s,%s" % (frm,limit)
    cursor.execute(sql)
    print "TOTAL RECORDS: "+str(cursor.rowcount)
    results = cursor.fetchall()
    count = 0;
    for row in results:
        try:
            domain = row[1].lower()
            idd = row[0]
            command = "/home/wasif/public_html/phantomjs /home/wasif/public_html/crawler2.js %s %s" % (domain,idd)
            print command
            proc = subprocess.Popen(command, shell=True, stdout=subprocess.PIPE)
            script_response = proc.stdout.read()
            print script_response
        except:
            print "error running crawler: "+domain

except:
    print "Error: unable to fetch data"
db.close()

データベースからドメインを選択する制限を設定するには、2 つの引数が必要です。

foreach ドメインを作成し、サブプロセスを使用してこのコマンドを実行します

command = "/home/wasif/public_html/phantomjs /home/wasif/public_html/crawler2.js %s %s" % (domain,idd)
command
proc = subprocess.Popen(command, shell=True, stdout=subprocess.PIPE)
script_response = proc.stdout.read()
        print script_response

crawler2.js ファイルも 2 つの引数を取ります。1 つはドメインで、2 番目は更新する ID です。クローラーが完了したときは = 1 です。これは、crawler2.js です。

var args = require('system').args;
var address = '';
var id = '';
args.forEach(function(arg, i) {
    if(i == 1){
       address = arg;
    }

    if(i == 2){
        id = arg;
    }
});

address = "http://www."+address;

var page = require('webpage').create(),
server = 'http://www.EXAMPLE.net/main/crawler',
data = 'url='+address+'&id='+id;

console.log(data);

page.open(server, 'post', data, function (status) {
    if (status !== 'success') {
        console.log(address+' Unable to post!');
    } else {
        console.log(address+' : done');
    }
    phantom.exit();
});

それはうまくいきますが、しばらくするとスクリプトが動かなくなり、しばらくしてから再起動する必要があり、ログには何も問題がありません

このプロセスを最適化し、できるだけ早くクローラーを実行する必要があります。

4

1 に答える 1

0

Web クローラー プログラマーがここにいます。:)

あなたのpythonはファントムを連続して実行します。並行して行う必要があります。それを行うには、ファントムを実行してからそのままにし、待機しないでください。

PHP では、次のようになります。

exec("/your_executable_path > /dev/null &");

必要がない場合は、ファントムを使用しないでください。すべてをレンダリングします。> 50MB のメモリが必要になります。

于 2015-03-01T09:06:25.943 に答える