2017-03-28 3 views
-1

私は、単純なhtml DOMを使用してコンテンツをスクラップするためにcurlを使用しています。私はコードを実行するのに多くの時間がかかるので、何千ものページをスクラップする必要があります。私は自分のコードをスピードアップできるメソッドを探しています。私はfile_get_contentsを使ってこれを行うことができると知っていますが、それはいくつかの呼び出しの後に私にエラーを与えます。ウェブページを最も効率的に廃棄する

これは私がこれまで行ってきたことです。誰かがこれをスピードアップする方法を指摘できれば素晴らしいだろう。どんな助けもありがとう。

<?php 
include_once ('simple_html_dom.php'); 

function do_it_with_curl($url) 
{ 
    $ch = curl_init(); 
    curl_setopt($ch, CURLOPT_URL, $url); 
    curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);  
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); 

    $server_output = curl_exec ($ch); 
    $error = curl_error($ch); 
    $errno = curl_errno($ch); 
    curl_close ($ch); 
    return str_get_html($server_output); 
} 

function check_response_object($str_obj, $type) 
{ 
    if(is_object($str_obj)) 
    { 
     if($type == 'url') 
     { 
      return $str_obj->href; 
     } else if ($type == 'text') 
     { 
      return $str_obj->plaintext; 
     } 
    } else 
    { 
     return false; 
    } 
} 
$scrap_url = ''; 
$scrap_err = ''; 
if ($_SERVER["REQUEST_METHOD"] == "POST") 
{ 
    if (empty($_POST["scrap_url"])) 
    { 
     $scrap_err = "URL is required"; 
    } else 
    { 
     $scrap_url = $_POST["scrap_url"]; 
     header('Content-Type: text/csv; charset=utf-8'); 
     header('Content-Disposition: attachment; filename=yellow-pages.csv'); 
     $output = fopen('php://output', 'w'); 
     fputcsv($output, array('Name', 'Website', 'Email', 'Phone', 'Address', 'Reference URL')); 
     $url = $scrap_url; 
     do 
     { 
      $html = do_it_with_curl($url); 
      $next_page = check_response_object($html->find('[rel="next"]', 0), 'url'); 
      $results = $html->find('div.organic div.result'); 
      foreach($results as $single_result) 
      { 
       $item = array(); 
       $next_url = check_response_object($single_result->find('a.business-name', 0), 'url'); 
       $next_html = do_it_with_curl($next_url); 
       if($next_html) 
       { 
        $item['name'] = check_response_object($next_html->find('h1[itemprop="name"]', 0), 'text'); 
        $item['website'] = check_response_object($next_html->find('a.website-link', 0), 'url'); 
        $item['email'] = substr(check_response_object($next_html->find('a.email-business', 0), 'url') , 7) ; 
        $item['phone'] = check_response_object($next_html->find('p.phone', 0), 'text'); 
        $item['address'] = check_response_object($next_html->find('h2[itemprop="address"]', 0), 'text'); 
        $item['ypref'] = strtok($next_url, '?'); 
       } 
       fputcsv($output , $item); 
      } 
      $url = $next_page; 
     } while ($next_page); 
     exit(); 
    } 
} 
?> 
<form method="post" action="<?php echo htmlspecialchars($_SERVER["PHP_SELF"]);?>"> 
    URL: 
    <input type="text" name="scrap_url" value="<?php echo $scrap_url;?>" style="width:80%;"> 
    <span class="error">* <?php echo $scrap_err;?></span> 
    <br><br> 
    <input type="submit" name="submit" value="Submit"> 
</form> 
+0

str_get_htmlとは何ですか? –

+0

FYI:file_get_contentsを調べる必要があります。この例では、カールを使用すべき理由はありません。 file_get_contentsは非常に簡単です。 –

+0

これは、curlの文字列出力を単純なhtml domオブジェクトに変換します。 – shazyriver

答えて

1

ボトルネックはcURLではありません。あなたの削り取り作業は、の順番にになるということです。何千ものWebページをスクラップすると、Webページを取得するためのHTTP要求、HTMLを読み取るための解析操作、CSVとして結果を保存するファイル操作からの遅延が発生します。

cURLから別のメカニズムに切り替えることで、パフォーマンスが大幅に向上することはありません。より良いアプローチは、アルゴリズムマルチスレッドを作成して、掻き取り操作がで起こるようにすることです。あなたはpthreads

pthreadsを使用してPHPでマルチスレッドを行うことができます

はPHPで、ユーザランドのマルチスレッド化を可能にするオブジェクト指向APIです。これには、Webまたはコンソールを対象とするマルチスレッドアプリケーションを作成するために必要なすべてのツールが含まれています。 PHPアプリケーションは、スレッド、ワーカー、スタック可能オブジェクトを作成、読み込み、書き込み、実行、同期することができます。

あなたはマルチスレッドとスレッドの簡単な例を見つけることができThreadPoolを作成し、例えば20のスレッドで言うと、別のスレッドがあなたのループから

foreach($results as $single_result) {...} 

をそれぞれの結果を扱うことができますプールはPHP documentationにあります。 Google検索でさらに多くの例を見つけることができます。

+0

あなたは良い点があります。私はこれを試してみる – shazyriver

関連する問題