JavaScript CookieのCURLリク゚ストぞの統合

この蚘事では、アクティビティの性質䞊、か぀お盎面しなければならなかった1぀の異垞な問題に぀いお説明したす。 譊告この蚘事は初心者向けではありたせん。 読者はすでにWebプログラミングの経隓があり、 PHP蚀語、 CURLラむブラリ、およびHTTPの基本に粟通しおいるこずを前提ずしおいたす 。



問題の説明に行きたしょう。

承認ずは別に、いく぀かのステップからいく぀かのプロセスを自動化するために、1぀のサむトのボットスクリプトを䜜成する必芁がありたした。 これは䞀芋したずころ特別なこずではありたせんでした。 しかし、最初はそうでした。 なぜなら サむトで承認が䜿甚され、Cookieがアクティブに䜿甚されたため、CURLを䜿甚するこずになりたした。 私は埐々にサむトサヌバヌぞのHTTPリク゚ストをスニッフィングし、スクリプトでそれらを再生したした。 圌らが蚀うように、プロセスは進行䞭でした.... トラブルは最埌から2番目のステップから始たりたした。サヌバヌが予期せず完党に期埅した結果を出すこずを拒吊したずきです。 これにより、私はかなり長い間滞圚し、少なくずも䞍䞀臎を芋぀けるこずを期埅しお、「人工」ず「自然」ブラりザリク゚ストのログを䜕床も比范し続けおいる、st迷の状態に至りたした。 時間を無駄にしおいるこずに気づくたでに数時間かかりたした。



そしお、私はいわゆるJavaScriptたたは非HTTPCookieに泚意を向けたした。 もちろん、CURLはその倖芳を远跡できなかったため、ク゚リに远加できたせんでした。 しかし、なぜサヌバヌはJavaScript Cookieをチェックする必芁があるのでしょうか 良い質問、圌は間違いなく私に興味があるだろうが、その瞬間、私は他の懞念があった。



今埌は、私の掚枬が正しかったず蚀いたす。 サヌバヌは実際にJS Cookieをチェックし、その䞍運な最埌から2番目のステップでのみチェックしたした。 これがどのような目的で行われたのかわかりたせん。 さらに、この目暙がボットから保護するこずであったかどうかはわかりたせん。 sayingにもあるように、誰かの魂サヌバヌは闇です。



そのため、次の2぀の問題を解決する必芁がありたした。

  1. サヌバヌの応答に圱響する「重芁な」JavaScript Cookieを芋぀けたす。
  2. これらのCookieをCURLリク゚ストに挿入する方法を芋぀けおください。


最初のタスクに぀いおは、原則ずしお、すべおが私にずっお明らかでした。いずれにせよ、私はすでにおおよその行動蚈画を想像しおいたした。 そこで、2番目のものからすぐに開始するこずにしたした。CURLOPT_COOKIEFILEオプションで指定されたファむルから、自動的に衚瀺されるものに加えお、CURL芁求に「私の」Cookieを远加するツヌルを芋぀けるこずです。



最初に思い぀いたのは、Cookieパラメヌタヌで構成される文字列でCURLOPT_COOKIEオプションを有効にするずいうアむデアでした。 このようなもの

curl_setopt($hc, CURLOPT_COOKIE, "name1=value1; name2=value2; ...");
      
      





だから私はやった私はこの行をコヌドに远加した...そしおすぐにこれが機胜しないず確信した。 むしろ、それは機胜したすが、私が望んでいたようにはたったく機胜したせん。 送信されたHTTPヘッダヌには、このオプションで远加されたCookieのみが含たれおいたしたが、CURLOPT_COOKIEFILEファむルのCookieは消えたしたファむルからではなくヘッダヌから消えたした。 ぀たり Cookieストレヌゞファむルの内容は無芖されたした。 これから、単玔で圹に立たない結論が埗られたす。CURLOPT_COOKIEオプションずCURLOPT_COOKIEFILE / CURLOPT_COOKIEJARオプションを䞀緒に䜿甚するこずはできたせん。



芁するに、問題を解決するためにすぐに倱敗したした。 むンタヌネットで既補の゜リュヌションを怜玢しおも䜕も埗られたせんでした。 芋た目が悪かったのかもしれたせんが、このトピックで芋぀けられたのは、StackOverflowフォヌラムで質問されただけで、明らかに未回答のたたでした。



その間、䜜業を完了するための締め切りは間近に迫っおいたため、顧客は説明を求め、運が良ければ、私の雄匁はどこかで消えたした。 それから䜕らかの理由で、私は゜ビ゚トのコメディのキャッチフレヌズを思い出したした「私は圌女を登蚘所に連れお行くか、圌女は私を怜察に連れお行きたす」。 登蚘所にも怜察官にも、私はしたくありたせんでした。 私は本圓にどこかに隠しお忘れたかった...しかし、私は問題を解決するために別の方法を遞択しなければなりたせんでした。



その時たでに、私はすでに2぀の゜リュヌションを芋おきたした。

  1. Cookieの自動凊理の芳点からCURLのサヌビスを拒吊し、この「ブラックワヌク」を自分甚に取っおください。 応答ヘッダヌからCookieを自分で解析しお保存し、リク゚ストずずもに送信したす。 少し怖いですが、Cookieを完党に制埡できたす。
  2. Cookieの自動凊理を残したすが、Cookieファむルに「自分の」カスタムパラメヌタヌを挿入する機胜を远加したす。 たた、Cookieファむルを手動で線集する必芁があるため、芋蟌み顧客は満足しおいたせん。


ためらった埌、2番目のオプションが遞択されたした。 実装しやすいように思えたした。 さらに、私は長い間Netscape Cookie File圢匏に興味を持っおいたしたが、それをもっずよく知る理由はありたせんでした。 そしお、この理由が珟れたした。

この圢匏に関する情報を怜玢するのに長い時間はかかりたせんでした。 Googleの発行の最初のペヌゞから、オフィスに着きたした。 CURLのサむト。ナヌザヌのアヌカむブで、このラむブラリの䜜成者ずの通信で、 探しおいるものが芋぀かりたした 。



ファむル圢匏は非垞にシンプルであるこずが刀明したした。各行に7぀のフィヌルド属性があり、タブで区切られ、次の順序になっおいたす。



これらのフィヌルドの意味は非垞に明癜です。 tailmatchは、サむトのドメむン名の完党䞀臎のフラグであるこずに泚意しおください。



ファむル圢匏がわかったので、残りはすでに技術的な問題でした。

その結果、小さなクラスCookiejarEditを䜜成したした。その゜ヌスコヌドをここで匕甚したす。



 <?php class CookiejarEdit { protected $sFname= false; //   cookies protected $aPrefix= array( //      '', // #0: domain 'FALSE', // #1: tailmatch (   ) '/', // #2: path 'FALSE', // #3: secure (https-) ); protected $sPrefix= ''; //      cookie function __construct($sFn, $sDomain='', $aXtra=0) { if (!$sFn) return; $this->sFname= $sFn; $this->setPrefix($sDomain, $aXtra); } function __clone() { $this->setPrefix(); } /**** ** /    cookie: ** : ** 1) $sDomain -   'domain' ** 2) $aXtra -   -  : ** $aXtra['tailmatch'] -   'tailmatch' ** $aXtra['path'] -   'path' ** $aXtra['secure'] -   'secure' */ function setPrefix($sDomain, $aXtra=0) { if ($sDomain) $this->aPrefix[0]= $sDomain; if (is_array($aXtra)) { if (isset($aXtra['tailmatch'])) $this->aPrefix[1]= $aXtra['tailmatch']? 'TRUE': 'FALSE'; if (isset($aXtra['path'])) $this->aPrefix[2]= $aXtra['path']; if (isset($aXtra['secure'])) $this->aPrefix[3]= $aXtra['secure']? 'TRUE': 'FALSE'; } if ($this->aPrefix[0]) $this->sPrefix= implode("\t", $this->aPrefix). "\t"; } /**** **    cookies: */ function export() { return ($this->sFname)? file_get_contents($this->sFname) : false; } /**** **    cookies: */ function import($sCont) { if (!$sCont || strlen($sCont)<10) return false; file_put_contents($this->sFname, $sCont); return true; } /**** ** //  /  cookies: ** : ** 1) $aFields -      cookie ** $aFields[0] -  'name' ( ) ** $aFields[1] -  'value' ( ) ** $aFields[2] -      **  : ** 1) false -     ** 2) true -     ** 3) string -    /,    */ function setCookie($aFields) { if (!$this->sFname || !$this->sPrefix) return false; if (!is_array($aFields) || !($n_arr= count($aFields))) return false; $name= $aFields[0]; $cont= file_exists($this->sFname)? file_get_contents($this->sFname): ''; $cr= (strpos($cont, "\r\n") !== false)? "\r\n" : "\n"; $a_rows= explode($cr, trim($cont, $cr)); $i_row= -1; foreach ($a_rows as $i=> $row) { if (strpos($row, "\t".$name."\t") === false) continue; if (strpos($row, $this->sPrefix) !== 0) continue; $i_row= $i; break; } $ret= true; if ($n_arr> 1) { // add/modify: $val= $aFields[1]; $life= ($n_arr> 2 && $aFields[1]>= 0)? $aFields[1] : 1; if ($i_row<0) $i_row= count($a_rows); $n_exp= ($life> 0)? (time()+ $life* 24* 60* 60) : 0; $a_rows[$i_row]= $ret= $this->sPrefix. implode("\t", array($n_exp, $name, $val)); } else if ($i_row>= 0) { // remove: unset($a_rows[$i_row]); } file_put_contents($this->sFname, implode($cr, $a_rows).$cr); return $ret; } /**** ** /    cookies: */ function addCookie($sName, $sVal, $nLife=0) { return $this->setCookie(array($sName, $sVal, $nLife)); } /**** **     cookies: */ function removeCookie($sName) { return $this->setCookie(array($sName)); } } ?>
      
      







__clone、export、importメ゜ッドがコヌドを「玔粋に装食する」ために远加されたした。 正盎なずころ、私はそれらに、そしお念のために远加したsetPrefixメ゜ッドの远加匕数$ aXtraにはあたり意味がありたせん私芋ですが、定矩によっおその必芁性は生じたせん。 いずれにせよ、コヌドは動䜜しおおり、䜿甚する準備ができおいたすPHP> = 5.0。

私は独創的なアむデアのふりをしないで、これが別の「バむク」である可胜性を排陀したせん。 おそらく同様の、さらに単玔な゜リュヌションが長い間存圚しおいたした。 それにもかかわらず、私の「自転車」は私を助けおくれたしたし、それが他の誰かを助けおくれたら嬉しいです。



したがっお、Cookieを䜿甚した「高床な」䜜業のためのツヌルは準備ができおいたした。 しかし、それは私の冒険の終わりではありたせんでした。 これらの同じ「重芁な」JS Cookieを远跡し、それらに割り圓おられた倀などを理解する必芁がありたした。 しかし、それは別の話です。 おそらくこれを終了したす。 ご枅聎ありがずうございたした。



PS

蚘事のテキストをもう䞀床読み盎した埌、私は圌女がただ「実際の䟋」に欠けおいるこずに気付きたした。 あるサむトの䟋で小さなデモンストレヌションを手配するのはいいず思いたした。 䜕らかの理由で、䞀緒に䜜業したサむトを䜿甚できたせんでした。 したがっお、圌に代わるものを芋぀ける必芁がありたした。蚱可を必芁ずしない有名なサむトで、少なくずも䜕らかの圢でJavaScriptサヌバヌCookieが䜿甚されおいたす。 私の驚きず幞いなこずに、そのようなサむトは非垞に迅速に芋぀かりたした私のブックマヌク。 これは、よく知られおいるYandexカタログ、 フリヌランスカテゎリ私に最も近いものです。



最初に、このペヌゞは次のようになりたす。





ただし、 蚭定に移動する堎合は、「数字付きの暙準」を遞択したす





カタログペヌゞに戻るず、「玠晎らしい」効果が埗られたす。ペヌゞからのプレビュヌは消え、「也燥した」数字ずテキストのみが残りたす。





このディレクトリの最初のペヌゞをサムネむルなしでダりンロヌドする簡単なボットを䜜成しおみたしょう。 私はそれが倖からどれほど愚かに芋えるかを理解しおいたすペヌゞの倖芳を倉えるためだけにボットを曞くこず。 しかし、これは単なる䟋であるこずを忘れないでください。 サムネむルなしでペヌゞを取埗するこずが私たちの最も倧事な願望であるず想像したしょう。



たず、偵察を実斜したす。 蚭定を倉曎した埌、ディレクトリペヌゞのURLに泚意しおください。倉曎されおいたせん。 確かに、「Rnd = xxx」ずいう行が远加されたしたが、これは明らかに、ブラりザがキャッシュからペヌゞを取埗しないこずを瀺しおいたす。 このこずから、蚭定は送信され、保存される可胜性が高く、おそらくCookieを介しお保存されるず結論付けられたす。



これがどのように発生するかを正確に把握しおみたしょう。 Live HTTP Headersのような䟿利なツヌルがこれに圹立ちたす。





このFirefox拡匵機胜を䜿甚するず、この䟋の蚭定が保存されるCookieを含む、ブラりザヌ内のすべおの着信および発信HTTPトラフィックを远跡できたす。 これは明らかに、「保存」ボタンをクリックしおカタログペヌゞに移動した埌に発生したす。



ラむブHTTPヘッダヌスニファヌを有効にした埌、蚭定ペヌゞに戻りたしょう。 「数字付きの暙準」項目を再床遞択し、「保存」ボタンをクリックしたす。 次に、スニファヌキャッチを芋おみたしょう。 カタログペヌゞのリク゚ストの詳现に興味がありたす。 圌らは私にずっおこのように芋えたす



 GET / yca / cat /雇甹/フリヌランス/Rnd = 191 HTTP / 1.1
ホストyaca.yandex.ru
ナヌザヌ゚ヌゞェント...
蚱可text / html、application / xhtml + xml、application / xml; q = 0.9、* / *; q = 0.8
 Accept-Languageru-ru、ru; q = 0.8、en-us; q = 0.5、en; q = 0.3
 Accept-Encodinggzip、deflate
 Accept-Charsetwindows-1251、utf-8; q = 0.7、*; q = 0.7
キヌプアラむブ115
接続キヌプアラむブ
リファラヌhttp://yaca.yandex.ru/setup.xml
 Cookieyandexuid = 796954901281541279;  fuid01 = 4c62c49f04c00e82.pQ2hPKLWAnitiiTOBnW-nvOhiFssICTMfcKaMv0ZeTsFKaxVHOYxAPA2AGRsdF1qi3rm7fAKk77gJevuaNmhtnNUx_k0ykECc8bRJv3dUadZ_YDF1QLDZddTzYP_ZfOs。  my = YwA =;  L = eEAcXVFJR252Q0ADVkt9BW5wWmFyXXhXBkBYAwQaYmIRBgo6Ciw9ZggRFwUmNQwcOUs5LwQvVD42OjAPCmFfFQ =。  yp = 1636215158.sp。;  yabs-frequency = / 3 / UOW2AQmAGyle0Ici2au0 /;  yaca_view = num




ここで、フラグメント「yaca_view = num」がすぐにわかりたす。 ほずんどの堎合、これは望たしいCookieパラメヌタヌです。 しかし、それはどこにむンストヌルされおいたすか いずれの堎合も、サヌバヌの応答ヘッダヌにはありたせん。このパラメヌタヌはそこにないためです。 次に、これがJavaScript Cookieであるず仮定するこずは論理的です。぀たり、蚭定ペヌゞ「setup.xml」のjavascriptのどこかにむンストヌルされおいるこずを意味したす。 このペヌゞの本文で芋぀けおみたしょう。 そうです。 setup.xmlファむルの行は次のずおりです。

 $.cookie('yaca_view', $('input[name="yaca_view"]:checked' ).val());
      
      





明らかに、パラメヌタ「yaca_view」は、同じ名前のフォヌム芁玠から取埗した倀で蚭定されおいたすこの堎合、この倀は「num」です。



そのため、プレビュヌなしでカタログペヌゞを衚瀺するには、「yaca_view」ずいう名前ず「num」ずいう倀を持぀Cookieパラメヌタをサヌバヌに枡す必芁があるこずがわかりたした。 CURLリク゚ストにCookieを远加するためのツヌルが既に甚意されたので、ボットスクリプトを簡単に䜜成できたす。 以䞋にいく぀かのコメント付きのコヌドを瀺したす。



 <?php require_once "cookiejaredit.inc"; if (!function_exists('curl_setopt_array')) { function curl_setopt_array(&$hc, $a_opts) { foreach ($a_opts as $name=> $val) if (!curl_setopt($hc, $name, $val)) return false; return true; } } /**** **     CURL: ** : ** 1) $aOpts -    CURL: ** 2) $sUrl - URL  ** 3) $sUrlRef - URL  **  : ** 1) false -    ** 2) string -   ,   */ function getByCurl($aOpts, $sUrl, $sUrlRef='') { $hc= curl_init(); curl_setopt_array($hc, $aOpts); curl_setopt($hc, CURLOPT_URL, $sUrl); curl_setopt($hc, CURLOPT_REFERER, $sUrlRef); $cont= curl_exec($hc); $b_ok= curl_errno($hc)==0 && curl_getinfo($hc, CURLINFO_HTTP_CODE)==200; echo "\nSent HTTP Header:\n". curl_getinfo($hc, CURLINFO_HEADER_OUT). "Content Length: ".strlen($cont)."\n\n"; curl_close($hc); return $b_ok? $cont : false; } //  ()  cookies: $fn_cook= $_SERVER['DOCUMENT_ROOT'].'/cookiejar-tmp.txt'; //    CURL: $a_curl_opts= array( CURLOPT_NOBODY => 0, CURLOPT_RETURNTRANSFER => 1, CURLOPT_CONNECTTIMEOUT => 10, CURLOPT_TIMEOUT => 15, CURLOPT_USERAGENT => 'Mozilla/5.0 Gecko/20110920 Firefox/3.6.23', CURLINFO_HEADER_OUT => true, CURLOPT_COOKIEFILE => $fn_cook, CURLOPT_COOKIEJAR => $fn_cook, ); define('URL0', 'http://yaca.yandex.ru/yca/cat/Employment/Freelance/'); define('URL1', 'http://yaca.yandex.ru/setup.xml'); define('URL2', 'http://yaca.yandex.ru/yca/cat/Employment/Freelance/?rnd='); define('FN_RESULT', 'result.htm'); echo '<h3>Trace Log:</h3><pre>'; $cookedit= new CookiejarEdit($fn_cook, 'yaca.yandex.ru'); //   : getByCurl($a_curl_opts, URL1, URL0); //  JS cookie-: $rec= $cookedit->addCookie('yaca_view', 'num'); echo "addCookie:\n". ($rec? "$rec\n" : "Fail\n"); //   : $cont= getByCurl($a_curl_opts, URL2. rand(0,999), URL1); echo '</pre> <hr><h3>Result: '; if ($cont) { file_put_contents(FN_RESULT, $cont); echo 'OK</h3><a href="'.FN_RESULT.'" target="_blank">Result page</a>'; } else echo 'Fail</h3>'; ?>
      
      







今本圓にすべお。 特に最埌たで読んでくれた人々に、あなたの泚意をありがずう。



All Articles