在采集大批量数据时常常会触发对方服务器的“自我保护”,请求过于频繁就限制访问。这时需要停留很长一段时间(十几分钟到几十分钟不等)才能恢复访问,这样采集数据的速度就受到非常大的限制。
同样经常会碰到需要自动换IP的需求,比方模拟点击投票,数据采集被封IP,Alexa作弊等等,也就是需要经常换IP的,我们都可以通过PHP控制路由器来换IP,这样就不需要用按键精灵搞得那么累了。呵呵。有的路由器是提供通过WEB方式管理路由器设置的,中间有一个功能就是断线和重新连接,可以利用这个功能。
解决方法有两个:
1 通过图片识别绕过验证码机制,告诉服务器:我不是蜘蛛,我是人。不信你瞧,我能看懂验证码。
2 更换IP,告诉服务器:我不是张三,我是李四。不信你瞧,我的IP地址和张三的不一样。
第一个方法难度稍高一点而且不靠谱,等哪天对方服务器升级了验证码了,这边也得跟进,麻烦多;而ISP(电信、联通、移动)那儿有很多IP,每次联网都会分配一个新的IP,因此方法二比较好。
以我的TP-LINK路由器为例,找到“网络参数”>“WAN口设置”,可以看到“自动连接”设置和“断线”按钮。每次点击“断线”按钮,就向ISP重新拨号,此时就换了一个IP。但大批量数据的采集需要的时间比较长,不可能总有人在旁边守着,最好能在PHP代码中,一旦发现被限制了就重启一次。
打开chrome浏览器的调试模式,然后点击“断线”按钮,看“Network”网络请求,可以看到实际执行的地址是:“http://192.168.1.1/userRpm/StatusRpm.htm?Disconnect=%B6%CF%20%CF%DF&wan=1”
然后模拟请求这个地址,经测试确实可以更换IP地址。接下来的就简单了:就用PHP使用Curl组件来实现这个请求的过程,我封装了一个函数resetip,具体代码如下:
ini_set("display_errors", "On");
error_reporting(E_ALL | E_STRICT);
echo "IP:".$_SERVER['REMOTE_ADDR']."
";
resetRouter();
function resetRouter() {
$username = 'admin';
$password = '5601928';
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'http://192.168.1.1/userRpm/StatusRpm.htm?Disconnect=%B6%CF%20%CF%DF&wan=1');
curl_setopt($ch, CURLOPT_USERPWD, "$username:$password");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
print_r($ch);
curl_exec($ch);
curl_close($ch);
}
方法二:
function router($target=´´){
$server = '192.168.1.1'; // IP address
$host = '192.168.1.1'; // Domain name
$port = '80';
$referer = 'http://'.$host.$target; // Referer
$username = 'admin';//#ADSL的路由的用户名
$password = '5601928';//#ADSL的路由的管理密码
$authorization = base64_encode($username.":".$password);
$File = fsockopen($server, $port, $errno, $errstr, 30);
if ($File) {
$out = "GET $target HTTP/1.1rn";
$out .= "Host: $hostrn";
$out .= "Referer: $refererrn";
$out .= "Authorization: Basic $authorizationrn";
$out .= "Connection: Closernrn";
fputs($File, $out);
$makeFile = $buffer = "";
while ($buffer = fread($File,4096)){
$makeFile = $makeFile.$buffer;
}
fclose($File);
}
}
//调用方法
router("/userRpm/StatusRpm.htm?Disconnect=%B6%CF%20%CF%DF&wan=1");