2013-06-01 13 views
28

Sto recuperando alcuni contenuti da un sito Web dopo l'invio di un modulo. Il problema è che lo script non funziona ogni tanto, diciamo 2 volte su 5 che lo script fallisce. Sto usando php curl, COOKIEFILE e COOKIEJAR per gestire il cookie. Tuttavia quando ho osservato le intestazioni inviate del mio browser (quando si visita il sito Web di destinazione dal mio browser e si utilizzano intestazioni HTTP in tempo reale) e le intestazioni inviate da php e visto ci sono molte differenze.Come posso inviare cookie usando PHP curl in aggiunta a CURLOPT_COOKIEFILE?

Il mio browser ha inviato molte più variabili di cookie rispetto a php curl. Penso che questa differenza potrebbe essere dovuta al fatto che javascript è suscettibile di impostare la maggior parte dei cookie, tuttavia non ne sono sicuro.

Sto usando il codice qui sotto per fare il raschiamento e sto mostrando le intestazioni inviati del mio browser e di PHP riccio:

$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& 

vorrei utilizzare:

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

e :

curl_setopt($ch, CURLOPT_HTTPHEADER, $headers); 

dove:

$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'; 

Alcuni dei parametri nel cookie sopra I potrebbero essere in grado di raschiare dal contenuto del sito Web, ma non tutti. Alcuni di loro potrebbero essere in grado di leggere dal $ ckfile, ma non so come farlo. Soprattutto l'utma utmc, utmz, utmcsr, utmccn, utmcmd non riesco ad andare da nessuna parte, penso che siano generate dal javascript.

Domanda 1: sto facendo qualcosa di sbagliato con la gestione dei cookie nel codice attuale come molto poche variabili di cookie vengono inviati per php curl e molto di più dal browser? Inoltre: le altre differenze tra le intestazioni inviate dal browser e php curl possono costituire un problema per restituire il contenuto giusto?

Domanda 2: Le variabili dei cookie mancanti sono dovute all'impostazione javascript di tali cookie?

Domanda 3: Qual è il modo migliore per gestire i cookie per assicurarsi che tutti i cookie richiesti vengano inviati al server remoto?

Il vostro aiuto è molto gradito!

+0

Ti sei mai trovato da queste parti? Sto vivendo lo stesso problema - chiedendo perché il browser invia 3 cookie e arriccia solo invia 1, anche se il file cookie contiene tutti 3. – David

+0

Hmmm ... sembra un problema sto avendo scraping backpage.com. – TARKUS

risposta

54

Se il cookie viene generato dallo script, è possibile inviare manualmente il cookie insieme al cookie dal file (utilizzando l'opzione cookie-file). Per esempio:

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

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

In questo caso arricciatura invierà il cookie definito insieme ai cookie dal file.

Se il cookie viene generato tramite javascrript, è necessario rintracciare come viene generato e quindi è possibile inviarlo utilizzando il metodo sopra (tramite http-header).

I utma utmc, utmz vengono visualizzati quando i cookie vengono inviati da Mozilla. Non dovresti scommettere più su queste cose.

Infine, il modo in cui si sta facendo va bene.Assicurati solo di utilizzare il percorso assoluto per i nomi dei file (ad esempio /var/dir/cookie.txt) anziché relativo.

Abilita sempre la modalità dettagliata quando si lavora con arricciatura. Ti aiuterà molto a rintracciare le richieste. Inoltre risparmierà molto tempo.

curl_setopt($ch, CURLOPT_VERBOSE, true); 
+0

Il file cookie salvato includerà il test = cookie? In caso contrario, come potrei ottenere cURL per salvare i cookie dalla richiesta di intestazione personalizzata? – brant

+0

Il file del cookie @brant scrive solo in base all'intestazione della risposta 'Set-cookie' dal server. Se il server non restituisce quel cookie con quell'intestazione, quel caso verrà ignorato. –

+3

L'ordine delle chiamate a curl_setopt è molto importante. imposta * CURLOPT_POST * ** dopo ** * CURLOPT_POSTFIELDS * e ti perdi in un bug difficile da trovare ... Analogamente, l'ordine nella soluzione sopra riportata è importante da mantenere. Scambialo e sostituisci tutto nel file cookie con "test = cookie" – rahmanisback

0

Credo che l'unico cookie di cui hai bisogno è JSESSIONID = xxx ..

anche mai il tuo cookie, becasuse qualcuno potrebbe accedere ai vostri dati personali in quel modo. Specialmente quando i cookie sono di sessione. Questi cookie smetteranno di funzionare una volta effettuato il logout del sito.