web-dev-qa-db-fra.com

Comment puis-je envoyer des cookies en utilisant PHP curl en plus de CURLOPT_COOKIEFILE?

Je suis en train de gratter du contenu d'un site Web après la soumission d'un formulaire. Le problème est que le script échoue de temps en temps, disons 2 fois sur 5, le script échoue. J'utilise php curl, COOKIEFILE et COOKIEJAR pour gérer le cookie. Cependant, lorsque j’ai observé les en-têtes envoyés de mon navigateur (lorsqu’ils visitaient le site Web cible depuis mon navigateur et utilisaient des en-têtes http vivants) et les en-têtes envoyés par php, nous avons constaté de nombreuses différences. 

Mon navigateur a envoyé beaucoup plus de variables de cookies que php curl. Je pense que cette différence pourrait être due au fait que javascript est responsable de la configuration de la plupart des cookies, mais je ne suis pas sûr de cela.

J'utilise le code ci-dessous pour faire le scraping et je montre les en-têtes envoyés de mon navigateur et de php curl:

$ckfile = tempnam ("/tmp", 'cookiename');

$url = 'https://www.domain.com/firststep';
$poststring = 'variable1=4&variable2=5';
$ch = curl_init ($url);
curl_setopt ($ch, CURLOPT_COOKIEJAR, $ckfile);
curl_setopt ($ch, CURLOPT_COOKIEFILE, $ckfile);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 30);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
curl_setopt ($ch, CURLOPT_POST, 1);
curl_setopt ($ch, CURLOPT_POSTFIELDS, $poststring);
$output = curl_exec ($ch);
curl_close($ch);



$url = 'https://www.domain.com/NeXTSTEP';
$poststring = 'variableB1=4&variableB2=5';
$ch = curl_init ($url);
curl_setopt ($ch, CURLOPT_COOKIEJAR, $ckfile);
curl_setopt ($ch, CURLOPT_COOKIEFILE, $ckfile);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 30);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
curl_setopt ($ch, CURLOPT_POST, 1);
curl_setopt ($ch, CURLOPT_POSTFIELDS, $poststring);
curl_setopt($ch, CURLINFO_HEADER_OUT, true);
$output = curl_exec ($ch);
$headers = curl_getinfo($ch, CURLINFO_HEADER_OUT);
curl_close($ch);

print_r($headers);

// Gives:
POST /d-cobs-web/doffers.html;jsessionid=7BC2A5277A4EB07D9A7237A707BE1366 HTTP/1.1
User-Agent: Mozilla
Host: domain.subdomain.nl
Accept: */*
Cookie: JSESSIONID=7BC2A5277A4EB07D9A7237A707BE1366; www-20480=MIFBNLFDFAAA
Content-Length: 187
Content-Type: application/x-www-form-urlencoded

// Where live http headers gives:
POST /d-cobs-web/doffers.html;jsessionid=7BC2A5277A4EB07D9A7237A707BE1366 HTTP/1.1
Host: domain.subdomain.nl
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:21.0) Gecko/20100101 Firefox/21.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: nl,en-us;q=0.7,en;q=0.3
Accept-Encoding: gzip, deflate
Content-Type: application/x-www-form-urlencoded; charset=UTF-8
Referer: https://domain.subdomain.nl/dd/doffers.html?returnUrl=https%3A%2F%2Fttcc.subdomain.nl%2Fdd%2Fpreferences.html%3FValueChanged%3Dfalse&BEGBA=&departureDate=13-06-2013&extChangeTime=&pax2=0&bp=&pax1=1&pax4=0&bk=&pax3=0&shopId=&xtpage=&partner=NSINT&bc=&xt_pc=&ov=&departureTime=&comfortClass=2&destination=DEBHF&thalysTicketless=&beneUser=&debugDOffer=&logonId=&valueChanged=&iDomesticOrigin=&rp=&returnTime=&locale=nl_NL&vu=&thePassWeekend=false&returnDate=&xtsite=&pax=A&lc2=&lc1=&lc4=&lc3=&lc6=&lc5=&BECRA=&passType2=&custId=&lc9=&iDomesticDestination=&passType1=A&lc7=&lc8=&Origin=NLASC&toporef=&pid=&passType4=&returnTimeType=1&passType3=&departureTimeType=1&socusId=&idr3=&xtn2=&loyaltyCard=&idr2=&idr1=&thePassBusiness=false&cid=14812
Content-Length: 219
Cookie: subdomainPARTNER=NSINT; JSESSIONID=CB3FEB3AC72AD61A80BFED91D3FD96CA; www-20480=MHFBNLFDFAAA; campaignPos=5; www-47873=MGFBNLFDFAAA; __utma=1.993399624.1370027094.1370040145.1370082133.5; __utmc=1; __utmz=1.1370027094.1.1.utmcsr=(direct)|utmccn=(direct)|utmcmd=(none); BCSessionID=5dc05787-c2c8-43e1-9abe-93989970b087; BCPermissionLevel=PERSONAL; __utmb=1.1.10.1370082133
Connection: keep-alive
Pragma: no-cache
Cache-Control: no-cache
AJAXREQUEST=_viewRoot&doffersForm=doffersForm&doffersForm%3AvalueChanged=&doffersForm%3ArequestValid=true&javax.faces.ViewState=j_id3&doffersForm%3Aj_id937=doffersForm%3Aj_id937&valueChanged=false&AJAX%3AEVENTS_COUNT=1&

Je voudrais utiliser:

$headers   = array();
$headers[] = 'Cookie: ' . $cookie;

et:

curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);

où:

$cookie = 'subdomainPARTNER=NSINT; JSESSIONID=CB3FEB3AC72AD61A80BFED91D3FD96CA; www-20480=MHFBNLFDFAAA; campaignPos=5; www-47873=MGFBNLFDFAAA; __utma=1.993399624.1370027094.1370040145.1370082133.5; __utmc=1; __utmz=1.1370027094.1.1.utmcsr=(direct)|utmccn=(direct)|utmcmd=(none); BCSessionID=5dc05787-c2c8-43e1-9abe-93989970b087; BCPermissionLevel=PERSONAL; __utmb=1.1.10.1370082133';

Certains des paramètres du cookie ci-dessus pourraient éventuellement être effacés du contenu du site Web, mais pas tous. Je pourrais peut-être lire certains d'entre eux à partir du fichier $ ckfile, mais je ne sais pas comment faire cela. Surtout les utma utmc, utmz, utmcsr, utmccn, utmcmd que je ne parviens pas à obtenir de n'importe où, je pense que ceux-ci sont générés par le javascript. 

Question 1: Est-ce que je fais quelque chose de mal avec la gestion des cookies dans le code actuel, car très peu de variables de cookies sont envoyées par php curl et beaucoup plus par le navigateur? En outre: d'autres différences entre les en-têtes envoyés par navigateur et php curl peuvent-elles poser un problème pour renvoyer le bon contenu?

Question 2: Les variables de cookie manquantes sont-elles dues au paramétrage javascript de ces cookies?

Question 3: Quel est le meilleur moyen de gérer les cookies pour s’assurer que tous les cookies requis sont envoyés au serveur distant?

Votre aide est la bienvenue!

32
BastiaanWW

Si le cookie est généré à partir d'un script, vous pouvez alors l'envoyer manuellement avec le cookie du fichier (à l'aide de l'option cookie-fichier). Par exemple:

# sending manually set cookie
curl_setopt($ch, CURLOPT_HTTPHEADER, array("Cookie: test=cookie"));

# sending cookies from file
curl_setopt($ch, CURLOPT_COOKIEFILE, $ckfile);

Dans ce cas, curl enverra votre cookie défini avec les cookies du fichier.

Si le cookie est généré via javascrript, vous devez le rechercher, puis vous pouvez l'envoyer à l'aide de la méthode ci-dessus (via http-header).

Les utma utmc, utmz sont visibles lors de l’envoi de cookies par Mozilla. Vous ne devriez plus vous soucier de ces choses-là.

Enfin, la façon dont vous faites est bien. Assurez-vous simplement que vous utilisez un chemin absolu pour les noms de fichiers (c'est-à-dire /var/dir/cookie.txt) au lieu d'un nom relatif.

Activez toujours le mode commenté lorsque vous travaillez avec curl. Cela vous aidera beaucoup à suivre les demandes. En outre, cela vous fera économiser beaucoup de temps.

curl_setopt($ch, CURLOPT_VERBOSE, true);
59
Sabuj Hassan

Je pense que le seul cookie dont vous avez besoin est JSESSIONID = xxx ..

Ne partagez jamais non plus vos cookies, car vous pourriez ainsi avoir accès à vos données personnelles. Spécialement lorsque les cookies sont en session. Ces cookies cesseront de fonctionner une fois que vous aurez déconnecté le site.

0
Atanas Atanasov

Essayez ci-dessous le code,

$cookieFile = "cookies.txt";
if(!file_exists($cookieFile)) {
    $fh = fopen($cookieFile, "w");
    fwrite($fh, "");
    fclose($fh);
}


$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $apiCall);
curl_setopt($ch, CURLOPT_POST, TRUE);
curl_setopt($ch, CURLOPT_POSTFIELDS, $jsonDataEncoded);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type: application/json'));
curl_setopt($ch, CURLOPT_COOKIEFILE, $cookieFile); // Cookie aware
curl_setopt($ch, CURLOPT_COOKIEJAR, $cookieFile); // Cookie aware
curl_setopt($ch, CURLOPT_VERBOSE, true);
if(!curl_exec($ch)){
    die('Error: "' . curl_error($ch) . '" - Code: ' . curl_errno($ch));
}
else{
    $response = curl_exec($ch); 
}
curl_close($ch);
$result = json_decode($response, true);

echo '<pre>';
var_dump($result);
echo'</pre>';

J'espère que cela t'aidera. 

Cordialement, Dasitha.

0
Dasitha Abeysinghe