3

非常に長いURLのリストを入力し、ソースコード内の特定の文字列を検索して、その文字列を含むURLのリストを出力したいと思います。簡単そうに聞こえますか?私は次のコードを思いついた。入力はhtmlフォームである。pelican-cement.com/findfrogで試すことができます。

半分の時間で動作するように見えますが、異なる順序の複数のURL/URLによってスローされます。「AdSense」を検索すると、politics1.comが正しく識別されます。

cnn.com
politics1.com

ただし、逆にすると、出力は空白になります。どうすれば信頼できる一貫した結果を得ることができますか?できれば、何千ものURLを入力できるものはありますか?

<html>
<body>

<?
set_time_limit (0);

$urls=explode("\n", $_POST['url']);

$allurls=count($urls);

for ( $counter = 0; $counter <= $allurls; $counter++) {

 $ch = curl_init();
 curl_setopt($ch, CURLOPT_URL,$urls[$counter]);
 curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
 curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
 curl_setopt($ch, CURLOPT_CUSTOMREQUEST,'GET');
 curl_setopt ($ch, CURLOPT_HEADER, 1); 
 curl_exec ($ch); 
 $curl_scraped_page=curl_exec($ch); 

$haystack=strtolower($curl_scraped_page);
$needle=$_POST['proxy'];
if (strlen(strstr($haystack,$needle))>0) {

echo $urls[$counter];
echo "<br/>";
curl_close($ch);
}
}




//$FileNameSQL = "/googleresearch" .  abs(rand(0,1000000000000000))  .  ".csv";
//$query = "SELECT * FROM happyturtle INTO OUTFILE '$FileNameSQL' FIELDS TERMINATED BY ','";
//$result = mysql_query($query) or die(mysql_error());

//exit;

echo '$FileNameSQL';





?>

</body>
</html>
4

4 に答える 4

1

おそらくあなたは電話する必要があります

curl_close($ch);

スクレイプされたページで文字列が見つかったかどうかに関係なく。それを除けば、コードに明らかに問題はありません。

コードに何かが含まれていない場合は、スクレイプされたページに何らかの違いがある可能性があります。たぶん、ページは動的であり、後続のチェックで常に針の単語が含まれているとは限りません。スクレイプしようとしたページのサーバーがエラーコードを返した可能性があります。

于 2011-04-12T22:44:16.657 に答える
1

いくつかの調整、それらが役立つかどうかはわかりませんが、それでも

$url_to_go = trim($urls[$counter]);
if($url_to_go){
 $ch = curl_init();
 curl_setopt($ch, CURLOPT_URL,$url_to_go);
 curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
 curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
 curl_setopt($ch, CURLOPT_CUSTOMREQUEST,'GET');
 curl_setopt ($ch, CURLOPT_HEADER, 1); 
 $curl_scraped_page=curl_exec($ch); 
 curl_close($ch);

 // more code follows
}
于 2011-04-12T22:45:15.067 に答える
1

それを捨てているのは、URLの周りのキャリッジリターン/空白でしょうか?入れる価値があるかもしれません

$urls[$counter] = trim($urls[$counter]);

forループの開始時。

また:

if (strpos($haystack, $needle) !== false) {
    [...]
}

ある文字列に別の文字列が含まれているかどうかを確認するためのより効率的な方法です。strtolower()の代わりにここでstriposを使用して、最初にすべてを実行することもできます(それで改善されるかどうかはわかりません)。

于 2011-04-12T22:46:58.860 に答える
1

コードを少し再編成しました。主な原因は空白でした。URL文字列を使用する前にトリミングする必要があります(つまりtrim($url);)。

その他の変更:

  • 検索語は変更されないため、forループの外側に設定します。
  • ループの外側にcurlオブジェクトを設定し、毎回URLを変更するだけで再利用できます。
  • curl_setopt_array()を使用して、1つのステートメントに複数のcurlオプションを設定します。
  • とにかく配列全体を反復処理していて、コードがよりクリーンであるため、foreachループを使用します。
  • stripos()の使用は、strstr()よりも効率的であり、とにかく大文字と小文字を区別しません。
  • !==コンパレータを使用して、暗黙の型キャストを防止します(FALSE!== 0、ただしFALSE == 0)。
  • curl_exec()が失敗するとFALSEを返す可能性があるため、返された$html文字列を確認してください。
  • 最後にcurlオブジェクトを閉じます(つまり、ifステートメントの外側も閉じます)。

以下のコードは、私のクイックモックアップで実行できます。

<html>
<body>

<form action="search.php" method="post"> 
  URLs: <br/>
  <textarea rows="20" cols="50" input type="text" name="url" /></textarea><br/>

  Search Term: <br/>
  <textarea rows="20" cols="50" input type="text" name="proxy" /></textarea><br/>

  <input type="submit" /> 
</form>

<?
  if(isset($_POST['url'])) {
    set_time_limit (0);

    $urls = explode("\n", $_POST['url']);
    $term = $_POST['proxy'];
    $options = array( CURLOPT_FOLLOWLOCATION => 1,
                      CURLOPT_RETURNTRANSFER => 1,
                      CURLOPT_CUSTOMREQUEST  => 'GET',
                      CURLOPT_HEADER         => 1,
                      );
    $ch = curl_init();
    curl_setopt_array($ch, $options);

    foreach ($urls as $url) {
      curl_setopt($ch, CURLOPT_URL, trim($url));
      $html = curl_exec($ch);

      if ($html !== FALSE && stristr($html, $term) !== FALSE) { // Found!
        echo $url;
      }
    }

    curl_close($ch);
  }
?>

</body>
</html>
于 2011-04-12T22:55:14.830 に答える