PHP curl, odczyt danych ze strony z logowaniem

0

Wykorzystując curl próbuję odczytać dane ze strony i zapisać je do pliku. Poniższy kod odczytuje mi stronę jako użytkownik niezalogowany. Czego mi brakuje, żeby strona zapisywana do pliku, była stroną, którą widzi użytkownik zalogowany?

$file = fopen("wyniki.txt", "w");
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $URL);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_USERPWD, "$username:$password");
curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_BASIC);
curl_setopt($ch, CURLOPT_FILE, $file);
$output = curl_exec($ch);
$info = curl_getinfo($ch);
curl_close($ch);
fclose($file);

Zmienne URL, username, password, są poprawne. Jeżeli podam jakąś stronę, gdzie nie jest potrzebne logowanie, to odczytuje dobrze.

0

Wyślij sobie formularz logowania pod adres jaki jest wykorzystywany do logowania na tej stronie. Odebrane ciastka wyślij w kolejnym curl już z zapytaniem o dane jakie tam sobie chcesz. Po prostu musisz przejść proces logowania jeśli to jest zwykła strona.

1

Otwórz sobie zakładkę sieć w przeglądarce. Kliknij na pierwsze żądanie do strony a następnie PPM -> Copy as cURL, potem tak samo z żądaniem logowania i z żądaniem pobierania pliku.

Jak już masz 3 te żądania, wpisz w google "curl to php", wejdź na pierwszy link i każde z żądań przerób na PHP.
Powinno zadziałać jak system jest prosty.

0
Markuz napisał(a):

Otwórz sobie zakładkę sieć w przeglądarce. Kliknij na pierwsze żądanie do strony a następnie PPM -> Copy as cURL, potem tak samo z żądaniem logowania i z żądaniem pobierania pliku.

Jak już masz 3 te żądania, wpisz w google "curl to php", wejdź na pierwszy link i każde z żądań przerób na PHP.
Powinno zadziałać jak system jest prosty.

Chyba nie do końca rozumiem, jak znaleźć żądanie logowania oraz pobierania pliku.

Zrobiłem tak, że znalazłem to pierwsze żądanie i przerobiłem na cUrl. W praktyce wyszło tak, że linijkę:

curl_setopt($ch, CURLOPT_USERPWD, "$username:$password");

zamieniłem na:

curl_setopt($ch, CURLOPT_POSTFIELDS, "ilogin=$username^&ipassword=$password");

Dzięki temu uzyskałem dostęp do danych ze strony głównej takie jak są po zalogowaniu. Tylko teraz jeżeli próbuję pobrać dane z jakiejś zakładki np. URL/statystyki, to wtedy już nie mam dostępu do tych danych. Jak sprawdzam żądania na tych podstronach i też zrobię tak, żeby zamienić cURL na PHP, to wtedy nigdzie tam nie pokazują się moje dane po zalogowaniu, więc zakładam, że są one gdzieś w cookies?
Jeżeli pobieram zawartość strony po zalogowaniu, to mogę też jakoś pobrać cookies, które będę mógł przekazywać jakoś do następnego curl_init():?
Czy jakoś inaczej powinienem to zrobić?

0

Tak, cURL ogarnia cookies - https://stackoverflow.com/questions/27958072/setting-a-cookie-in-php-curl/27958251
Gdybyś zrobił to co Ci mówiłem, to miałbyś prawdopodobnie obsługę cookies już w kodzie.

0
$headers = array();
$headers[] = 'Cookie: tutaj odczytane cookies';
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);

Czyli chodzi o coś takiego? I teraz tak, jak tutaj mam cookies to normalnie w jednej funkcji zrobić ten kod co mam i potem znowu cURL_init() i wtedy inny URL docelowy + cookies z pierwszego?

0

Nie, powinno wystarczyć tylko wskazanie plików cookies przy każdym żądaniu:

curl_setopt($ch, CURLOPT_COOKIEJAR, '/tmp/cookies.txt');
curl_setopt($ch, CURLOPT_COOKIEFILE, '/tmp/cookies.txt');

A skrypt już sam zapisze co trzeba w trakcie logowania, i jak będziesz pobierał plik do cURL wczyta sobie z tych plików cookies które się wcześniej zapisały.

0
$file = fopen("wyniki.txt", "w");

      $ch = curl_init();
      curl_setopt($ch, CURLOPT_URL, 'główna');
      curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
      curl_setopt($ch, CURLOPT_POSTFIELDS, "ilogin=$username^&ipassword=$password");
      curl_setopt($ch, CURLOPT_POST, 1);
      curl_setopt($ch, CURLOPT_ENCODING, 'gzip, deflate');
      curl_setopt($ch, CURLOPT_COOKIEJAR, 'cookies.txt');
      curl_setopt($ch, CURLOPT_FILE, $file);

      $output = curl_exec($ch);
      $info = curl_getinfo($ch);
      curl_close($ch);
      fclose($file);

      echo $output;


      $file = fopen("wyniki3.txt", "w");
      $ch = curl_init();
      curl_setopt($ch, CURLOPT_URL, 'podstrona');
      curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
      curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'GET');
      curl_setopt($ch, CURLOPT_ENCODING, 'gzip, deflate');
      curl_setopt($ch, CURLOPT_COOKIEFILE, 'cookies.txt');
      curl_setopt($ch, CURLOPT_FILE, $file);

      $output = curl_exec($ch);
      $info = curl_getinfo($ch);
      curl_close($ch);
      fclose($file);

      echo $output;

Pierwsza część pobiera dane ze strony jako zalogowany, więc to działa dobrze. Tworzy też plik cookies. Druga część, dalej pobiera z podstrony jako niezalogowany. Źle przekazuje plik cookies?

0

Dlaczego raz używasz CURLOPT_COOKIEFILE a za drugim razem CURLOPT_COOKIEFILE? Użyj ich jednocześnie w dwóch miejscach.

0

W sensie CURLOPT_COOKIEJAR i CURLOPT_COOKIEFILE?
Bo CURLOPT_COOKIEJAR odpowiada za zapis, a CURLOPT_COOKIEFILE za odczyt?

P.S.
Umieszczenie obu linii w obu miejscach, nie zmienia efektu końcowego.

0

Pokaż kod wynikowy. Co w tym pliku z cookies się okłada? Gdzie wyczytałeś, że CURLOPT_COOKIEJAR odpowiada za zapis a CURLOPT_COOKIEFILE za odczyt?

0

Z manuala:
CURLOPT_COOKIEFILE The name of the file containing the cookie data. The cookie file can be in Netscape format, or just plain HTTP-style headers dumped into a file. If the name is an empty string, no cookies are loaded, but cookie handling is still enabled.
CURLOPT_COOKIEJAR The name of a file to save all internal cookies to when the handle is closed, e.g. after a call to curl_close.

CURLOPT_COOKIEJAR - tutaj podaję plik, gdzie mają być zapisywane cookies.
CURLOPT_COOKIEFILE - tutaj wskazuję plik, gdzie są zapisane dane cookies.

Może, źle to rozumiem.

W pliku cookies.txt tworzy się taka zawartość:

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

sokker.org	FALSE	/	FALSE	253402210800	lang	pl
sokker.org	FALSE	/	FALSE	253402210800	lang_ID	1
sokker.org	FALSE	/	FALSE	253402210800	_html_rtl	0
sokker.org	FALSE	/	FALSE	0	PHPSESSID	buf2rc7vvs3nloqlapiqpm1nh2
sokker.org	FALSE	/	FALSE	1551870616	hide_promotion	1
sokker.org	FALSE	/team/teamID/	FALSE	253402210800	conf	1432970172
0

Ok, wygląda na to, że sesja się zapisała - A czy w odpowiedzi na żądanie z logowaniem jest informacja, że się zalogowałeś poprawnie? (Możesz sobie wypluć odpowiedź w przeglądarce/CLI).

0

A jest możliwość, że mogę się zalogować niepoprawnie, skoro z pierwszej strony głównej odczytuje dane po zalogowaniu?

0

Skoro tak, to raczej problem jest w innym miejscu.

Z tym kopiowaniem cURL to był najprostszy sposób, ale skoro to gra, to możliwe, że chcesz nabijać automatycznie jakieś rzeczy i się przed tym zabezpieczyli - mogli to robić na wiele różnych sposobów, musisz dokładnie przeanalizować co się dzieje w zakładce "Sieć/Network" przed lub w trakcie wysyłania tego problematycznego żądania.

0

W sumie o tym nie pomyślałem.
Chcę po prostu odczytać dane, które są normalnie widoczne w kodzie (źródło strony), więc nie jest do tego potrzebny dostęp do jakiś baz danych, czy gdzie te informacje się finalnie znajdują.
W kodzie wygląda to tak, że jest

i po prostu samą wartość bym chciał odczytać.
Chyba nie jest kwestia zabezpieczeń, skoro normalnie widzę kod i te wartości, i sam string chcę pobrać?</p>
1

Przykro mi ale nie będę Ci w stanie pomóc chyba, że zrobię to za Ciebie - a tego nie chcę. Próbuj a na pewno się uda - jak nie dzisiaj to może za tydzień ;)

Źródło strony w przeglądarce a to otrzymane z serwera to 2 różne rzeczy, skąd wiesz, że ta wartość nie jest np. pobierana w tle i wstawiana tam dynamicznie przez JS?

0

Chcę zrobić sam, więc i tak dzięki za pomoc. Jestem już dalej niż byłem.
To takie jeszcze pytanie, jeżeli JS wrzuca tę zawartość dynamicznie na stronę, to jest możliwość odczytania tego co zostaje wyświetlone?

1

Tak, ale raczej nie po stronie PHP - chociaż dało by się to obejść. Proponuję dowiedzieć się (jeżeli to faktycznie JS wstawia) skąd on bierze tą zmienną - i w PHP się dobić bezpośrednio do źródła tych danych (które niekoniecznie będzie takie samo jak to wyświetlane, np. może być bez formatowania albo lekko zdekodowane jak ktoś był ambitny i to coś delikatnego).

Sprawdź czy w źródle strony jest ta informacja tj. wejdź na view-source//4programmers.net/ tylko z odpowiednim linkiem. Jak jest to spoko, jak nie ma to analizuj zakładkę sieć i szukaj w którym żądaniu (a raczej odpowiedzi żądania) znajduje się ta informacja której szukasz.

0

Dzięki bardzo za pomoc

1 użytkowników online, w tym zalogowanych: 0, gości: 1