snoopy采集https,会调用curl模块,因为要确保安装了该模块,并且指明了路径。(snoopy默认指定的就是正确的)
构建一个表单提交
asp的站点会有些隐含的参数,要从页面中全部扣出来。
$submit_url = "https://www.example.com/login.aspx";//提交页面
$formvars["DropDownList1"] = "zh-CN";
$formvars["txtAccount"] = "11111";
$formvars["txtPassword"] = "111111";
$formvars["txtLoginCode"] = $_GET['a']; //填写验证码
$formvars["Button1"] = "";
$formvars["__EVENTTARGET"] = "";
$formvars["__EVENTARGUMENT"] = "";
$formvars["__LASTFOCUS"] = "";
$formvars["__VIEWSTATE"] = "/wEPDffUKFgICAg8QZGQWAQGS/KEtAfsT5lfgRPVAoWIJarrT2zA==";
$sp = new Snoopy;
$sp->cookies["ASP.NET_SessionId"] = $_GET['s']; //设置sessionID的cookie
$sp->submit($submit_url,$formvars);
var_dump($sp->results);//获取表单提交后的 返回的结果
if( !empty($sp->error)) { //如果有错误,返回错误
var_dump($sp->error);
}
返回的信息是 Object Moved To Here;直接无视。
这时候已经登陆了,可以对要获取的页面进行采集。
$geturl = 'http://www.example.com/product/content.aspx';
$sp->fetch($geturl);
if ($sp->status != 200) {
echo 'no get status: '.$sp->status.'<br/>';
} else {
$file_contents = $sp->results;
echo 'get content:<br/>';
echo $file_contents;
echo '<br/>';
}
如果你是在window环境下使用snoopy,curl会有问题,采集不到所要的内容。
建议在linux环境下进行。但很可能和操作系统没有关系,而只是php版本的问题,导致采集不到内容。
你也可以用该登陆模块来实现通过程序发帖的功能,不过每次的验证码和sessionid都要自己手动填写。
曾经想过,存在cookie中的sessionid能不能通过程序读取,发现没办法跨域读取cookie。因此ff下,只能借助firebug
来查看,ie下借助httpwatch查看
引申1
curl是利用url语法在命令行下使用的一个下载工具,它有多个参数可以配置,支持ssh、cookie、post、get等操作;
引申2
关于多篇文章的并列下载,建议使用 multi curl,这样虽然php没有多线程的概念,但是使用multi curl可以达到多线程的效果,效率可以提升很多;其效率比串行的curl提高多倍以上,当然在网络传输比较慢的时候,性能提升更明显;使用方式如:
$start = microtime_float();
$arr_url = array(
'http://news.17173.com/content/2011-08-08/20110808113620769,1.shtml',
'http://news.17173.com/content/2011-08-08/20110808102240929,1.shtml',
'http://news.17173.com/content/2011-08-08/20110808102004067,1.shtml',
'http://news.17173.com/content/2011-08-08/20110808090759928,1.shtml'
);
$save_to = './save_multi/';
$mh = curl_multi_init();
$conn = array();
foreach($arr_url as $i=>$val){
$save_file = $save_to. basename($val);
if( !is_file($save_file)){
$conn[$i] = curl_init($val);
$fp[$i] = fopen($save_file, 'w');
curl_setopt($conn[$i], CURLOPT_USERAGENT, "Mozilla/4.0 (compatible;MSIE 7.0; Windows NT 6.0)");
curl_setopt($conn[$i], CURLOPT_FILE, $fp[$i]);
curl_setopt($conn[$i], CURLOPT_HEADER, 0);
curl_setopt($conn[$i], CURLOPT_CONNECTTIMEOUT, 60);
curl_multi_add_handle($mh, $conn[$i]);
}
}
//do{ //这段小代码有dirty,因为$active要等全部url数据接受完毕才变成false,会导致cpu跑到100%,不建议使用;
// $n = curl_multi_exec($mh, $active);
//}while($active);
//使用下面这段代码,可以使cpu不做无谓的花销:当有数据的时候就不停调用curl_multi_exec,暂时没有数据就进入select阶段,新数据一来就可以被唤醒继续执行。
do {
$mrc = curl_multi_exec($mh,$active);
} while ($mrc == CURLM_CALL_MULTI_PERFORM);
while ($active and $mrc == CURLM_OK) {
if (curl_multi_select($mh) != -1) {
do {
$mrc = curl_multi_exec($mh, $active);
} while ($mrc == CURLM_CALL_MULTI_PERFORM);
}
}
foreach($arr_url as $i=>$val){
curl_multi_remove_handle($mh, $conn[$i]);
curl_close($conn[$i]);
fclose($fp[$i]);
}
$end = microtime_float();
echo ($end - $start);
文章原创---转载注明来自 蜗牛的空间