0

次の関数は、URL を表す文字列パラメーターを受け取り、その URL を simple_html_dom オブジェクトにロードします。ロードに失敗した場合は、URL のロードを再試行します。

  public function getSimpleHtmlDomLoaded($url)
  {
    $ret = false;
    $count = 1;
    $max_attemps = 10;
    while ($ret === false) {
      $html = new simple_html_dom();
      $ret = $html->load_file($url);
      if ($ret === false) {
        echo "Error loading url: $url\n";
        sleep(5);
        $count++;
        $html->clear();
        unset($html);
        if ($count > $max_attemps) 
          return false;
      }
    }
    return $html;
  }

ただし、URL の読み込みが 1 回失敗すると、現在の URL で失敗し続け、処理が終了した後max attempsも、処理する必要がある残りの URL を使用して、関数の次の呼び出しでも失敗し続けます。

URL が一時的にオフラインの場合は失敗し続けるのが理にかなっていますが、そうではありません (スクリプトの実行中に確認しました)。

これが適切に機能しない理由はありますか?

また、URL のロードに失敗し始めると、(複数の警告ではなく) 警告のみが表示され、次のメッセージが表示されることも指摘したいと思います。

PHP 警告: file_get_contents(http://www.foo.com/resource): ストリームを開くことができませんでした: HTTP 要求が失敗しました! simple_html_dom.php の 1081 行目

次のコード行によってプロンプトが表示されます。

$ret = $html->load_file($url);
4

2 に答える 2

1

私はあなたのコードをテストしましたが、私にとっては完璧に機能します。その関数を呼び出すたびに、最初から有効な結果が返されます。

そのため、同じドメインからページをロードした場合でも、ページまたはサーバー上で何らかの保護が行われる可能性があります。たとえば、ページがいくつかの Cookie を検索したり、サーバーがユーザー エージェントを検索したりして、ユーザーがボットであると見なされた場合、正しいコンテンツを提供しません。

一部のWebサイトの解析中に同様の問題が発生しました。私への答えは、ページ/サーバーが何を期待しているかを確認し、コードでそれをシミュレートすることでした。ユーザー エージェントの偽装から Cookie の生成まで、すべてです。

ところで、単純な html dom パーサーがエラーなしでサーバー上で実行できることをテストするためだけに、単純な php スクリプトを作成しようとしましたか? それが私が最初に確認することです。

最後に、1 つのページの解析に何度も失敗し、マスキング ゲームに勝つことができなかった場合に、それを追加する必要があります。最後に、そのページをLinuxコマンドラインテキストブラウザlynxにロードし、ページ全体をローカルに保存するスクリプトを作成し、そのローカルファイルを解析して完璧に機能させました.

于 2012-09-27T08:13:49.270 に答える
0

load_file()関数自体の問題かもしれません。

問題は、関数 error_get_last() が以前のすべてのエラーも返すことでした。不明ですが、PHP のバージョンに依存している可能性があります。

私はそれを次のように変更することで問題を解決しました(nullであるかどうかではなく、エラーが変更されたかどうかを確認します)(または非オブジェクト関数を使用します: file_get_html()):

function load_file()
{
    $preerror=error_get_last();
    $args = func_get_args();
    $this->load(call_user_func_array('file_get_contents', $args), true);
    // Throw an error if we can't properly load the dom.
    if (($error=error_get_last())!==$preerror) {
        $this->clear();
        return false;
    }
}
于 2013-10-12T08:28:10.103 に答える