Autor | Zpráva | ||
---|---|---|---|
m93a Profil |
#1 · Zasláno: 14. 10. 2012, 19:42:09 · Upravil/a: m93a
Dobrý den,
zkoušel jsem udělat něco jako neoficiální API pro Strava.cz, ale narazil jsem na problém, který nemůžu vyřešit. Vytvořil jsem funkci pro přihlášení (file_get_contents, údaje přeneseny přes GET), a podařilo se mi načíst hlavní stránku, ale vždy, když zkusím načíst stránku objednavky.aspx nebo odhlaseni.aspx, file_get_contents vyhodí chybu 'failed to open stream: HTTP request failed! HTTP/1.1 500 Internal Server Error'. Zkoušel jsem všechno možné (dokonce jsem v prohlížeči sledoval HTTP hlavičky, ale nepřišel jsem na rozdíl, který by chybu mohl způsobit). Už jsem se ptal všude možně, ale řešení jsem nenašel. Byl bych hrozně rád, kdybyste mi někdo dokázal pomoci. Předem díky, m93a. Tady je můj současný PHP kód: <?php $strava_czUserAgent="User-Agent:(none; StravaCekujNET; Linux x86_64; rv:1.0)\r\n"; $strava_czHandle="n/a"; /** * * * * * * * * * * * * * * * * * Přihlášení (strava_czLogin) * * * * * * * * * * * * * * * * * * @param int|string $machine Zařízení (4 číslice, string v případě, že začíná nulou) * @param int|string $user Uživatel (10 číslic, string v případě, že začíná nulou) * @param string $pass Heslo pro přihlášení * * * * * */ function strava_czLogin($machine,$user,$pass){ global $strava_czUserAgent; global $strava_czHandle; //Zašle první požadavek > $dom $src = file_get_contents('http://m.strava.cz/Stravnik/formprihlaseni.aspx',false,stream_context_create(array('http'=>array('header' => $strava_czUserAgent)))); $src = mb_convert_encoding($src,'utf-8','auto'); //Zajistí správné kódování $dom = new domDocument; //Vytvoří DOM $doc->strictErrorChecking = FALSE; $dom->loadHTML($src); //Načte HTML unset($http_response_header, $src); //Uvolní paměť //Zpracuje přijatá data a zjistí klíč > $key $query['viewstate'] = $dom->getElementById('__VIEWSTATE')->getAttribute('value'); $query['eventvalidation'] = $dom->getElementById('__EVENTVALIDATION')->getAttribute('value'); $key = '?__EVENTTARGET'. '&__EVENTARGUMENT'. '&__VIEWSTATE='.urlencode($query['viewstate']). '&__EVENTVALIDATION='.urlencode($query['eventvalidation']). '&ctl00%24ContentPlaceHolder1%24txtZarizeni='.urlencode($machine). '&ctl00%24ContentPlaceHolder1%24txtUzivatel='.urlencode($user). '&ctl00%24ContentPlaceHolder1%24txtHeslo='.urlencode($pass). '&ctl00%24ContentPlaceHolder1%24butOdeslat=Odeslat'; unset($dom, $query); //Uvolní paměť //Zašle požadavek > $src, $http_response_header $src = file_get_contents('http://m.strava.cz/Stravnik/formprihlaseni.aspx'.$key,false,stream_context_create(array('http'=>array('header' => $strava_czUserAgent)))); $src = mb_convert_encoding($src,'utf-8','auto'); //Zajistí správné kódování unset($key); //Uvolní paměť //Zpracuje přijaté sušenky (mňam!) $i = 1; $strava_czHandle = array(); $strava_czHandle['cookies'] = ""; foreach ($http_response_header as $value) { $preg = preg_match('/^Set-Cookie:\s*.[^=]*=.[^;]*/m', $value, $matches); if ($preg) { foreach ($matches as $match) { $strava_czHandle['cookies'] .= substr($match, 12); //Zápis do handleru } } } unset($i, $http_response_header, $matches, $match, $value); //Uvolní paměť } /** * * * * * * * * * * * * * * * * * Odhlášení (strava_czLogout) * * * * * * * * * * * * * * * * * */ function strava_czLogout(){ global $strava_czUserAgent; global $strava_czHandle; if ($strava_czHandle=="n/a") {throw new Exception("notLogged");} //Zašle požadavek $src = file_get_contents('http://m.strava.cz/Stravnik/odhlaseni.aspx',false,stream_context_create(array('http'=>array('header' => $strava_czUserAgent."Cookie: ".$handle['cookies']."\r\n")))); $src = mb_convert_encoding($src,'utf-8','auto'); //Zajistí správné kódování //Zkontroluje správnost přijatých dat if (preg_match('<form name="aspnetForm" method="post" action="Default.aspx" id="aspnetForm">',$src)){ $strava_czHandle="n/a"; } else { throw new Exception("invalid"); } } A tady je zhruba průběh toho, co potřebuji, v prohlížeči: /stravnik/formprihlaseni.aspx request: nic response: content obsahuje _EVENTTARGET, _EVENTARGUMENT, _EVENTVALIDATION a _VIEWSTATE /stravnik/formprihlaseni.aspx request: cookie ASP.NET_SessionId postem asptákoviny (_EVENTTARGET, _EVENTARGUMENT, _EVENTVALIDATION a _VIEWSTATE) postem ctl00$ContentPlaceHolder1$txtZarizeni postem ctl00$ContentPlaceHolder1$txtUzivatel postem ctl00$ContentPlaceHolder1$txtHeslo postem ctl00$ContentPlaceHolder1$txtOdeslat s hodnotou 'Odeslat' response: cookie ASP.NET_SessionId 302 -> /stravnik/stravnik.aspx /stravnik/stravnik.aspx request: cookie ASP.NET_SessionId response: content obsahuje _VIEWSTATE /stravnik/objednavky.aspx request: cookie ASP.NET_SessionId response: content obsahuje asptákoviny a jídla (<tr class="tblObjednavkyDatum">...</tr><tr class="tblObjednavkyNazev">...</tr>) /stravnik/objednavky.aspx request: cookie ASP.NET_SessionId postem _EVENTTARGET s hodnotou 'butOdeslat2' a další asptákoviny postem možnosti (např. 2012-10-091 = 'radObjednavkaP424') response: 302 -> /stravnik/stravnik.aspx /stravnik/stravnik.aspx request: cookie ASP.NET_SessionId response: content obsahuje asptákoviny /stravnik/odhlaseni.aspx request: cookie ASP.NET_SessionId response: 302 -> /default.aspx |
||
Tori Profil |
#2 · Zasláno: 14. 10. 2012, 19:46:02
Pokud to v prohlížeči funguje, ale file_get_contents ne, tak může být problém v tom, že cílový server kontroluje existenci (a možná obsah) hlavičky User-Agent. Zkuste použít cUrl a příslušnou hlavičku nastavit (hledejte i tu na diskusi, curl se řešil dostkrát).
|
||
m93a Profil |
User-Agent mám nastaveno hned na prvním řádku (máš pravdu, bez něj to nešlo), ale tím se mi podařilo načíst jen tu zmíněnou přihlašovací stránku. Taky se mi podařilo zjistit, že kamarád má stejný problém v prohlížeči. Vyzkouším, jestli se to nespraví, když použiju zcela totožnou hlavičku, jako ve svém prohlížeči (ne jen User-Agent). Pak se ozvu.
Ale díky za radu :) Edit: Přidal jsem k hlavičce "Accept:(text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8)\r\nAccept-Language:(cs,sk;q=0.8,en;q=0.6,en-gb;q=0.4,en-us;q=0.2)\r\nAccept-Encoding:(gzip, deflate)\r\nDNT:(1)\r\nConnection:(keep-alive)\r\n" a vypadá to, že to zatím funguje. Snad to není jen dočasně (u serverů Mrkvosoftu nikdo neví :D). Díky Torle.
|
||
Časová prodleva: 12 let
|
0