Autor Zpráva
uestla
Profil
Dobrý podvečer.
Čirá zoufalost mě přiměla založit toto téma... O co jde:

Již delší dobu se snažím pomocí PHP vydolovat
z webu www.geocaching.com počet mnou nalezených
cachí.

Bohužel při řešení narážím na spoustu problémů
a paradoxů.

Geocaching.com totiž neposkytuje veřejné API
(alespoň o něm nevím... ?) a cizím službám nedůvěřuji
(rozumějte nechci jim svěřovat údaje ke svému
geoúčtu).

Pokoušel jsem se tedy pomocí CURL přihlásit
a z údajů o svém účtu vyparsovat kýžené číslo.
Ono totiž není bez přihlášení veřejnosti přístupné.

Jelikož je aplikace napsaná v ASP.NET, je třeba
z přihlašovacího formuláře vyparsovat ViewState
a podobné bordely, bohužel se mi nepodařilo
přihlášení provést.

Největším utrpením je pro mě fakt, že statistika
počtu nálezů je přitom dostupná pomocí tzv.
status baru, tj. obrázku, na kterém je počet
nálezů vyobrazen. Tento obrázek je navíc přístupný
veřejnosti.

Nechápu tedy, proč nemohou udělat jednoduchoučké
veřejné API, když už mají stejnou logiku zabudovanou
v oněch status barech...

Na jejich fórum jsem již ptal, ale asi se tam
nevyskytuje moc lidí z programátorské obce...

Obracím se tedy s prosbou na vás, a sice
zda máte někdo podobnou zkušenost, či jste
dokonce popsané strasti překonali a dosáhli
požadovaného čísla (o nic víc mi opravdu nejde)?

Předem děkuji za odpověď
a omlouvám se za dlouhý text.
Chro
Profil
Co takhle v PHP stáhnout status bar, obrázek prohnat nějakou OCR třídou a údaje o počtu nalezených/založených keších vyparsovat?
ShiraNai7
Profil
Přihlášení a následné vyparsování nějaké hodnoty by neměl být problém, třeba pomocí curl v PHP.. já osobně bych to řešil přes své komponenty, ale ty jsou PHP 5.4+. Taky tam nemám účet, abych to mohl vyzkoušet :)
uestla
Profil
Chro:
OCR jsem zkoušel, díky za tip. Bohužel jsem
pro PHP nenašel snadno nic použitelného...

ShiraNai7:
O pokusu přihlásit se přes PHP CURL píši. Nicméně
přihlásit se úspěšně do ASP.NET aplikace vyžaduje
fištróna... Zvládli by tvoje komponenty i tohle?
ShiraNai7
Profil
uestla:
Můžu to zkusit, ale jak jsem psal, účet tam nemám a registrovat se mi nechce :) Pokud máš nějaký testovací..
Chro
Profil
uestla:
Skript níže ber spíš jako kuriozitu. Dle uid stáhne požadovaný status bar, proskenuje oblast za "Found:" a až narazí na znak lomítka zobrazí výsledek. Vyzkoušeno na 42 status barech, u všech správný výsledek. Samozřejmě pokud Groundspeak změní grafickou podobu banneru, nemusí to fungovat.
<?php
$uid = '';
$link = 'http://img.geocaching.com/stats/img.aspx?txt=&uid='.$uid.'&bg=1';
$data = file_get_contents($link);
$masky_znaku = array(
'01410242034304440545',
'1020',
'00404142332415',
'0041233344450646',
'20112102122223240515253526',
'1222324344450646',
'10400102031323330444054546',
'403225',
'4041234405450646',
'000141024213233343444506',
'2115'
);
$od_x = 93;
$od_y = 23;
$vysledek = '';
$preruseni = 'ne';
$img = imagecreatefromstring($data);
for ($s = 0; $s < 100 && $preruseni == 'ne'; $s++)
{
$vyrez = imagecreatetruecolor(5, 7);
imagecopy($vyrez, $img, 0, 0, $od_x + $s, $od_y, 5, 7);
$maska_znaku = '';
for ($h = 0; $h < 7; $h++)
{
for ($w = 0; $w < 5; $w++)
{
$barva = imagecolorat($vyrez, $w, $h);
$rgb = imagecolorsforindex($vyrez, $barva);
if($rgb['red'] < 50 && $rgb['green'] < 50 && $rgb['blue'] < 50)
{
$maska_znaku.= $w.$h;
}
}
}
imagedestroy($vyrez);
foreach ($masky_znaku as $index => $hodnota)
{
if ($hodnota == $maska_znaku)
{
if ($index == 10)
{
$preruseni = 'ano';
}
else
{
$vysledek.= $index;
}
}
}
}
imagedestroy($img);
echo 'Found: '.$vysledek;
?>
<!-- Status bar pro kontrolu -->
<img src="<?php echo $link; ?>">
uestla
Profil
Chro:
Čoveče moc díky, ten kód zkusím otestovat
a dám vědět, jak dopadnu...
uestla
Profil
Funguje to! Absolutně nemám tušení, jaká
je za tím magie, ale hlavně, že výsledek je
očekávaný :-)

Jakožto Nette příznivce jsem kód malinko
učesal:

$char_masks = array(
    '01410242034304440545',
    '1020',
    '00404142332415',
    '0041233344450646',
    '20112102122223240515253526',
    '1222324344450646',
    '10400102031323330444054546',
    '403225',
    '4041234405450646',
    '000141024213233343444506',
    '2115'
);

$starts = array(
    'x' => 93,
    'y' => 23,
);

$result = '';
$image = Nette\Image::fromString( $curl->get( 'http://img.geocaching.com/stats/img.aspx?uid=...' )->body );

for ($i = 0; $i < 100; $i++) {
    $crop = Nette\Image::fromBlank(5, 7);
    $crop->copy($image, 0, 0, $starts['x'] + $i, $starts['y'], 5, 7);

    $char_mask = '';
    for ($j = 0; $j < 7; $j++) {
        for ($k = 0; $k < 5; $k++) {
            $colour = $crop->colorAt($k, $j);
            $rgb = $crop->colorsForIndex($colour);

            if ($rgb['red'] < 50 && $rgb['green'] < 50 && $rgb['blue'] < 50) {
                $char_mask .= $k . $j;
            }
        }
    }

    $crop->destroy();

    foreach ($char_masks as $index => $hodnota) {
        if ($hodnota === $char_mask) {
            if ($index === 10) {
                break 2;
            } else {
                $result .= $index;
            }
        }
    }
}

$image->destroy();
$result = (int) $result;

Mockrát děkuju!

Vaše odpověď

Mohlo by se hodit

Příspěvky nesouvisející s webem budou odstraněny.

Prosím používejte diakritiku a interpunkci.

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