在采集大批量数据时常常会触发对方服务器的“自我保护”,请求过于频繁就限制访问。这时需要停留很长一段时间(十几分钟到几十分钟不等)才能恢复访问,这样采集数据的速度就受到非常大的限制。
同样经常会碰到需要自动换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");