Autor Zpráva
m93a
Profil
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
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.

Vaše odpověď

Mohlo by se hodit


Prosím používejte diakritiku a interpunkci.

Ochrana proti spamu. Napište prosím číslo dvě-sta čtyřicet-sedm: