Check alle échte Black Friday-deals Ook zo moe van nepaanbiedingen? Wij laten alleen échte deals zien

[PHP] Sessie i.c.m. CURL in PHP CLI

Pagina: 1
Acties:

  • xoniq
  • Registratie: April 2005
  • Laatst online: 20-11 14:06
Beste,

Ik moet voor een klant hun site spideren, dit gebeurt dan ook via CURL, ook zit hier een login in, zou geen probleem moeten zijn met CURL.
Echter ik kom het volgende probleem tegen.

Als ik een login post naar hun site, heeft de resultaat bron de inlog data die ik verwacht.
Echter als ik binnen diezelfde CURL sessie een volgende pagina aanroep waarvoor je ingelogd moet zijn, dan heb ik die data niet meer.

Om het nog wat vager te maken, in het onderstaande script haal ik uit de headers de gegenereerde sessie-cookie op, die zet ik in een variable, en geef ik weer mee aan de volgende 'call'.
Maar dan ben ik niet ingelogd. De waarde van de '$cookie'-variable klopt qua inhoud. Als ik dan in mijn browser inlog op die site, en de PHPSESSID data uit de browser kopieer naar de broncode van de 2e call (dus die data zet ik in de '$cookie'-variable) dan ben ik bij de 2e call ineens wel altijd ingelogd

Het script om de CURL aanvragen te doen:

code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
$postinfo = "login=<USERNAME>&password=<PASSWORD>";

$ch = curl_init();

// First request
curl_setopt($ch, CURLOPT_URL, '<URL>');
curl_setopt($ch, CURLOPT_COOKIESESSION, true);
curl_setopt($ch, CURLOPT_USERAGENT, "Mozilla/5.0 (Windows; U; Windows NT 5.0; en-US; rv:1.7.12) Gecko/20050915 Firefox/1.0.7");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);

// Set post
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST");
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $postinfo);

curl_setopt( $ch, CURLOPT_FAILONERROR, false );
curl_setopt( $ch, CURLOPT_FOLLOWLOCATION, false );
curl_setopt( $ch, CURLOPT_HEADER, true );
curl_setopt( $ch, CURLOPT_COOKIESESSION, true );
curl_setopt( $ch, CURLOPT_FRESH_CONNECT, true );

$postresult = curl_exec($ch); // Has the login data

// Set cookie
$pattern = "#Set-Cookie: (.*?; path=.*?)\n#";
preg_match_all($pattern, $postresult, $matches);
$cookie = $matches[ 1 ][ 0 ];


/*
    Deze voeg ik dan toe vanuit de browser sessie.
    Dan ben ik wel ineens ingelogd in de onderstaande call.
    $cookie = 'PHPSESSID=6jnufr5rs73jvaa41lele1rk83; path=/';
*/


// New request
curl_setopt($ch, CURLOPT_URL, '<URL>');
curl_setopt($ch, CURLOPT_COOKIE, $cookie );
curl_setopt($ch, CURLOPT_AUTOREFERER, true);
curl_setopt($ch, CURLOPT_COOKIESESSION, true);
curl_setopt($ch, CURLOPT_FAILONERROR, false);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, false);
curl_setopt($ch, CURLOPT_FRESH_CONNECT, true);
curl_setopt($ch, CURLOPT_HEADER, false);
curl_setopt($ch, CURLOPT_POST, false);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 30);

$html = curl_exec($ch); // Has no login data
curl_close($ch);


Iemand enig idee?

  • glashio
  • Registratie: Oktober 2001
  • Laatst online: 21-11 13:08

glashio

C64 > AMIGA > PC

> Google Certified Searcher
> Make users so committed to Google that it would be painful to leave
> C64 Gospel
> [SjoQ] = SjoQing


  • encryped
  • Registratie: Juli 2008
  • Laatst online: 20-11 10:47
Meestal slaat cUrl alle cookies in een cookie file. Word deze gegenereerd ?. Ook als je best wel veel paginas wil gaan spiden zou ik https://code.google.com/p/rolling-curl/ gebruiken. Hiermee kan je parrallel paginas ophalen.

  • xoniq
  • Registratie: April 2005
  • Laatst online: 20-11 14:06
@glashio

De opties CURLOPT_COOKIEJAR en CURLOPT_COOKIEFILE heb ik tevens ook geprobeerd, echter dan werkt zelfs het 'sideloaden' van een browser cookie niet meer, de cookie wordt wel geldig weggeschreven hoor, daar niet van.

Dit is de output van mijn cookie file die is aangemaakt tijdens de CURL request, maar dan wil deze toch de inlog niet onthouden:

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

<URL>    FALSE   /       FALSE   0       PHPSESSID       9pl99082p2dfpr2htduo0kvj17


@encryped

Zie bovenstaand, heb beide manieren geprobeerd, direct doorsturen, sideloaden en via een cookie file, none of the above.
Verder hoef ik enkel die ene pagina te spideren, vandaar dat het een enkele CURL request is in simpele opzet.
Toch bedankt voor je suggestie zal die onthouden.

  • encryped
  • Registratie: Juli 2008
  • Laatst online: 20-11 10:47
Het zou kunnen zijn dat het login process ook via javascript loopt. Omdat de PHP session id wel werkt in je lokale browser. Probeer eens de session id over te nemen in een browser waar javascript uit staat.

  • xoniq
  • Registratie: April 2005
  • Laatst online: 20-11 14:06
Vreemd, ik probeer dat met JS uit, dan krijg ik een melding dat de gegevens onjuist zijn.
Maar als ik het via CURL doe, de data direct posten naar de afhandeling pagina, werkt het wel, want met een RegEx controleer ik of de source sporen bevat dat ik ben ingelogd, en daar ben ik dat dan ook.

  • Ultimation
  • Registratie: Februari 2010
  • Laatst online: 19-09 13:56

Ultimation

Het is als Appels en peren

Even los van het probleem. Waarom wil je deze website gaan spideren?

MacBook Pro 2023 [14-inch, M2 Pro, 32GB RAM, 512GB]


  • xoniq
  • Registratie: April 2005
  • Laatst online: 20-11 14:06
Spideren is een groot woord, het gaat slechts om een enkele pagina voor productvergelijking doeleinden van enkele websites die 'hierbij' aangesloten zijn.

  • Barryvdh
  • Registratie: Juni 2003
  • Laatst online: 21-11 14:12
Misschien kan je een bestaande scraper gebruiken, bijvoorbeeld https://github.com/fabpot/Goutte ?
Of in elk geval proberen of dat wel werkt?

code:
1
2
3
4
5
6
7
$crawler = $client->request('GET', 'http://github.com/');
$crawler = $client->click($crawler->selectLink('Sign in')->link());
$form = $crawler->selectButton('Sign in')->form();
$crawler = $client->submit($form, array('login' => 'fabpot', 'password' => 'xxxxxx'));
$crawler->filter('.flash-error')->each(function ($node) {
    print $node->text()."\n";
});

  • xoniq
  • Registratie: April 2005
  • Laatst online: 20-11 14:06
Dat functioneert wel op mijn locale dev omgeving, maar op server niveau niet. (Geen phar ondersteuning)

  • Barryvdh
  • Registratie: Juni 2003
  • Laatst online: 21-11 14:12
CRXDelSol schreef op dinsdag 28 oktober 2014 @ 12:39:
Dat functioneert wel op mijn locale dev omgeving, maar op server niveau niet. (Geen phar ondersteuning)
Je hoeft die phar niet te gebruiken, je kan ook gewoon composer gebruiken om hem te installeren (Goutte 2 voor php5.4+, anders Goutte 1 gebruiken nog)

  • xoniq
  • Registratie: April 2005
  • Laatst online: 20-11 14:06
Krijg bij Composer een fout op guzzlehttp die PHP versie 5.4+ nodig heeft, en 1 van onze servers draait op versie 5.3x.

  • Barryvdh
  • Registratie: Juni 2003
  • Laatst online: 21-11 14:12
CRXDelSol schreef op dinsdag 28 oktober 2014 @ 13:14:
Krijg bij Composer een fout op guzzlehttp die PHP versie 5.4+ nodig heeft, en 1 van onze servers draait op versie 5.3x.
Dat zeg ik toch? En staat ook in de readme.
If you need support for PHP 5.3 or Guzzle 3, use Goutte 1.0.6.
Dus gewoon 1.x in je composer.json zetten.

  • glashio
  • Registratie: Oktober 2001
  • Laatst online: 21-11 13:08

glashio

C64 > AMIGA > PC

PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
header('Content-Type: text/plain');

if ($_POST) {
    session_start();
    setcookie('foo', 'bar');
    print_r($_COOKIE);
    print_r($_SESSION);
    $_SESSION = $_SERVER;
    exit;
}

$h = curl_init('{SERVER/PATH}test.php');
curl_setopt($h, CURLOPT_POST, true);
curl_setopt($h, CURLOPT_POSTFIELDS, 'foo=bar');
curl_setopt($h, CURLOPT_HEADER, true);
curl_setopt($h, CURLOPT_RETURNTRANSFER, true);

$result = curl_exec($h);
$header = strstr($result, "\r\n\r\n", true);
$body = substr($result, strlen($header) + 4);
$cookie = preg_match_all('/^Set-Cookie: ([^;\s]+)/m', $header, $m) ? implode('; ', $m[1]) : '';

curl_setopt($h, CURLOPT_COOKIE, $cookie);
echo curl_exec($h);


Zet dit als test.php op je httpserver. Vervang {SERVER/PATH}test.php met je eigen http:// locatie.
En analyseer de output in je webbrowser :)

[ Voor 4% gewijzigd door glashio op 28-10-2014 14:00 . Reden: header(...) stond niet goed ]

> Google Certified Searcher
> Make users so committed to Google that it would be painful to leave
> C64 Gospel
> [SjoQ] = SjoQing


  • xoniq
  • Registratie: April 2005
  • Laatst online: 20-11 14:06
Van mijn locale webserver waar ik de CURL requests mee doe:

code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
HTTP/1.1 200 OK
Date: Tue, 28 Oct 2014 13:02:32 GMT
Server: Apache/2.4.9 (Unix) PHP/5.6.2
X-Powered-By: PHP/5.6.2
Expires: Thu, 19 Nov 1981 08:52:00 GMT
Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0
Pragma: no-cache
Set-Cookie: foo=bar
Content-Length: 1034
Content-Type: text/plain;charset=UTF-8

Array
(
    [PHPSESSID] => fb94hvi4h546qk57t4kmoefpt0
    [foo] => bar
)
Array
(
    [HTTP_HOST] => localhost
    [HTTP_ACCEPT] => */*
    [CONTENT_LENGTH] => 7
    [CONTENT_TYPE] => application/x-www-form-urlencoded
    [PATH] => /usr/bin:/bin:/usr/sbin:/sbin
    [SERVER_SIGNATURE] => 
    [SERVER_SOFTWARE] => Apache/2.4.9 (Unix) PHP/5.6.2
    [SERVER_NAME] => localhost
    [SERVER_ADDR] => ::1
    [SERVER_PORT] => 80
    [REMOTE_ADDR] => ::1
    [DOCUMENT_ROOT] => /Projects
    [REQUEST_SCHEME] => http
    [CONTEXT_PREFIX] => 
    [CONTEXT_DOCUMENT_ROOT] => /Projects
    [SERVER_ADMIN] => you@example.com
    [SCRIPT_FILENAME] => /Projects/test.php
    [REMOTE_PORT] => 64536
    [GATEWAY_INTERFACE] => CGI/1.1
    [SERVER_PROTOCOL] => HTTP/1.1
    [REQUEST_METHOD] => POST
    [QUERY_STRING] => 
    [REQUEST_URI] => /test.php
    [SCRIPT_NAME] => /test.php
    [PHP_SELF] => /test.php
    [REQUEST_TIME_FLOAT] => 1414501352.104
    [REQUEST_TIME] => 1414501352
)

  • glashio
  • Registratie: Oktober 2001
  • Laatst online: 21-11 13:08

glashio

C64 > AMIGA > PC

PHP:
1
print_r($_SESSION);


geeft data, dus je PHPSESSID is geladen in de 2de curl_exec request. Opgelost?

> Google Certified Searcher
> Make users so committed to Google that it would be painful to leave
> C64 Gospel
> [SjoQ] = SjoQing

Pagina: 1