0

ユーザーがスクリプトを介して画像にアクセスするのに問題があるという質問に遭遇しました(cURL/を使用file_get_contents()):

PHPを使用してURLから画像を保存するにはどうすればよいですか?

file_get_contents()画像リンクを使用してリクエストすると、403エラーが返されるようです。ただし、cURLでは、より詳細なエラーが返されます。

システムへのアクセスが拒否されました。本当にアクセスしたい場合は、エンジンまたはSurf Proxy、偽のIPをオフにしてください。プロキシまたはWebツールの侵入防止システムから受け入れられない。

Binh Minh Online Data Services @ 2008-2012

また、自分でcURLリクエストをいじった後、同じ画像にアクセスできませんでした。ユーザーエージェントを、画像に正常にアクセスできる正確なブラウザのユーザーエージェントに変更してみました。また、個人のローカルサーバーでスクリプトを試しました。このサーバーは(明らかに)ブラウザと同じIPアドレスを使用しています...私の知る限り、ユーザーエージェントとIPアドレスは状況に関係していません。

他に誰かがリクエストを実行しているスクリプトを検出できますか?

ところで、これはクレイジーなことではありません。私はxDに興味があります

4

1 に答える 1

6

これは確かに JavaScript によって設定された Cookie であり、元の画像へのリダイレクトです。問題は、curl/fgc が html を解析せず、サーバーによって設定された唯一の Cookie を設定して、curl が Cookie jar に保存することです。

これは、リダイレクトの前に取得するコードです。JavaScript を介して、名前はなく location.href を値として持つ Cookie を作成します。

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<HEAD>
<TITLE>http://phim.xixam.com/thumb/giotdang.jpeg</TITLE>
<meta http-equiv="Refresh" content="0;url=http://phim.xixam.com/thumb/giotdang.jpeg">
</HEAD>
<script type="text/javascript">
window.onload = function checknow() {
var today = new Date();
var expires = 3600000*1*1;
var expires_date = new Date(today.getTime() + (expires));
var ua = navigator.userAgent.toLowerCase();
if ( ua.indexOf( "safari" ) != -1 ) { document.cookie = "location.href"; } else { document.cookie = "location.href;expires=" + expires_date.toGMTString(); }
}
</script>
<BODY>
</BODY></HTML>

ただし、Cookie を事前設定/偽造することで、このセキュリティ対策を回避できるため、すべてが失われるわけではありません (あらゆる種類のセキュリティに Cookie を使用することが悪い理由です)。

cookie.txt

# Netscape HTTP Cookie File
# http://curl.haxx.se/rfc/cookie_spec.html
# This file was generated by libcurl! Edit at your own risk.

phim.xixam.com  FALSE   /thumb/ FALSE   1338867990      location.href

したがって、完成した curl スクリプトは次のようになります。

<?php
function curl_get($url){
    $return = '';
    (function_exists('curl_init')) ? '' : die('cURL Must be installed!');

    //Forge the cookie
    $expire = time()+3600000*1*1;
    $cookie =<<<COOKIE
# Netscape HTTP Cookie File
# http://curl.haxx.se/rfc/cookie_spec.html
# This file was generated by libcurl! Edit at your own risk.

phim.xixam.com  FALSE   /thumb/ FALSE   $expire     location.href

COOKIE;
    file_put_contents(dirname(__FILE__).'/cookie.txt',$cookie);

    //Browser Masquerade cURL request
    $curl = curl_init();
    $header[0] = "Accept: text/xml,application/xml,application/json,application/xhtml+xml,";
    $header[0] .= "text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5";
    $header[] = "Cache-Control: max-age=0";
    $header[] = "Connection: keep-alive";
    $header[] = "Keep-Alive: 300";
    $header[] = "Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7";
    $header[] = "Accept-Language: en-us,en;q=0.5";
    $header[] = "Pragma: ";

    curl_setopt($curl, CURLOPT_COOKIEJAR, dirname(__FILE__).'/cookie.txt');
    curl_setopt($curl, CURLOPT_COOKIEFILE, dirname(__FILE__).'/cookie.txt');
    curl_setopt($curl, CURLOPT_URL, $url);
    curl_setopt($curl, CURLOPT_USERAGENT, 'Mozilla/5.0 (Windows NT 5.1; rv:5.0) Gecko/20100101 Firefox/5.0 Firefox/5.0');
    curl_setopt($curl, CURLOPT_HTTPHEADER, $header);
    curl_setopt($curl, CURLOPT_HEADER, 0);
    //Pass the referer check
    curl_setopt($curl, CURLOPT_REFERER, 'http://xixam.com/forum.php');
    curl_setopt($curl, CURLOPT_ENCODING, 'gzip,deflate');
    curl_setopt($curl, CURLOPT_AUTOREFERER, true);
    curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($curl, CURLOPT_FOLLOWLOCATION, true);
    curl_setopt($curl, CURLOPT_TIMEOUT, 30);
    curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);

    $html = curl_exec($curl);
    curl_close($curl);
    return $html;
}

$image = curl_get('http://phim.xixam.com/thumb/giotdang.jpeg');

file_put_contents('test.jpg',$image);
?>

クローラーを停止する唯一の方法は、すべての訪問者の IP をデータベースに記録し、IP ごとの訪問数に基づいて値を増やしてから、1 週間に 1 回ほど IP ごとのトップ ヒットを調べてから、IP の逆ルックアップを行い、ホスティングプロバイダーからのものかどうかを確認し、ファイアウォールまたは htaccess でブロックします。それ以外の場合は、ハードルを克服できるため、リソースが公開されている場合、リソースへの要求を実際に停止することはできません。

それが役に立てば幸い。

于 2012-06-05T03:56:58.050 に答える