我在提交表单后从网站上抓取一些内容。问题是脚本时不时地失败,比如说5个脚本失败了2次。我正在使用php curl,COOKIEFILE和COOKIEJAR来处理cookie。但是,当我观察我的浏览器发送的标题(从我的浏览器访问目标网站并使用实时http标头)和php发送的标题时,看到有很多不同之处。
我的浏览器发送了比php curl更多的cookie变量。我认为这种差异可能是因为javascript可用于设置大多数cookie,但我不确定这一点。
我正在使用以下代码进行抓取,我正在显示我的浏览器和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&
我想用:
$headers = array();
$headers[] = 'Cookie: ' . $cookie;
和
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
其中:
$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';
我上面的cookie中的一些参数可能会从网站的内容中删除,但不是全部。其中一些我可以从$ ckfile中读取,但我不知道该怎么做。尤其是utma utmc,utmz,utmcsr,utmccn,utmcmd我无法从任何地方获取,我认为这些都是由javascript生成的。
问题1: 我在当前代码中处理cookie时出错了,因为很少有cookie变量是由php curl发送的,浏览器还有很多?进一步:浏览器和php curl发送的标题之间的其他差异是否能够返回正确的内容?
问题2: 由于javascript设置了这些cookie,是否缺少cookie变量?
问题3: 处理cookie以确保将所有必需的cookie发送到远程服务器的最佳方法是什么?
非常欢迎你的帮助!
答案 0 :(得分:63)
如果cookie是从脚本生成的,那么您可以手动将cookie与文件中的cookie一起发送(使用cookie-file选项)。例如:
# sending manually set cookie
curl_setopt($ch, CURLOPT_HTTPHEADER, array("Cookie: test=cookie"));
# sending cookies from file
curl_setopt($ch, CURLOPT_COOKIEFILE, $ckfile);
在这种情况下,curl会将您定义的cookie与文件中的cookie一起发送。
如果cookie是通过javascrript生成的,那么你必须追踪它是如何生成的,然后你可以使用上面的方法(通过http-header)发送它。
从Mozilla发送Cookie时会看到utma utmc, utmz
。你不应该再担心这些事了。
最后,你做的方式没问题。只需确保使用文件名的绝对路径(即/var/dir/cookie.txt
)而不是相对路径。
使用curl时始终启用详细模式。它将帮助您追踪请求。它也会节省你的很多时间。
curl_setopt($ch, CURLOPT_VERBOSE, true);
答案 1 :(得分:1)
尝试以下代码,
$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>';
我希望这会对您有所帮助。
最好的问候, 达西莎。
答案 2 :(得分:0)
以下是发送Cookie的示例列表-https://github.com/andriichuk/php-curl-cookbook#cookies
$curlHandler = curl_init();
curl_setopt_array($curlHandler, [
CURLOPT_URL => 'https://httpbin.org/cookies',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_COOKIEFILE => $cookieFile,
CURLOPT_COOKIE => 'foo=bar;baz=foo',
/**
* Or set header
* CURLOPT_HTTPHEADER => [
'Cookie: foo=bar;baz=foo',
]
*/
]);
$response = curl_exec($curlHandler);
curl_close($curlHandler);
echo $response;
答案 3 :(得分:-1)
我认为您需要的唯一Cookie是JSESSIONID = xxx ..
也绝不分享您的cookies,因为有人可能会以这种方式访问您的个人数据。特别是当cookie是会话时。一旦您退出网站,这些cookie将停止工作。