声明
本文教程仅供学习使用,未经允许请勿随意传播
环境
- Lunix服务器
- LNMP网站服务程序
别跟我说你不知道什么是LNMP!百度科普一下吧!
- ThinkPHP 5最新版
我测试的时候用的是RC4版,如果你看到本教程时,有更新的版本,应该不影响。
演示
暂未演示
效果图
教程
本教程是我在学习的过程中,无聊之作,有解释不清或者漏洞的地方,请大家指出,谢谢!!
本章全集主要是讲球球大作战分享链接的自动点击,主要有以下知识点
- PHP定时任务
- PHP小规模数据处理(多线程处理)
- PHP网页爬虫
PHP网页爬虫
大多数新手看到这里可能会疑惑,讲球球大作战分享链接的自动点击为什么要用到爬虫,在这里我给大家解释一下。
刚开始玩球球大作战时,游戏要求每个玩家都要去邀请别人来玩,就是把自己的分享链接发给别人,别人打开就是给自己增加棒棒糖,我当初想,这样太麻烦了吧,然后就想自己写个PHP程序来自动点击(PHP真牛),说着是自动点击,其实是模拟点击,在自己的PHP服务器发送http请求给球球大作战的网站服务器,让它误以为是真实的用户。
怎样能让它知道请求是真实的呢?使用PHP curl模块就可以做到,但是要使用代理IP。
代理IP哪里来?我百度了一下“代理IP”,然后有好多的免费代理IP可以使用
这个链接是我找到的,至少在我做的时候,很好用。每天都更新代理IP,这里我们只需用到HTTP代理,当然你可能有疑问,这么多IP我要一条一条的存到数据库吗?每天更新都要亲自动手吗?
当然不
这里就使用到了 PHP 爬虫,下面是我写的一个函数,它的功能就是通过这个链接的页面,自动抓取IP地址,并返回数组:
function getTodayIp() {
// 代理IP抓取地址
$str = curl('http://www.youdaili.net/Daili/http/');
if (empty($str))
return null;
$str = strip_tags($str,"<div><a>");
$str = getSubstr($str,"<div class="newslist_body">","</div>");
$str = str_replace( ["<br>","\n","\n\r","\r"], '', $str);
$ipPageList = explode('</a>', $str);
$ipList = [];
foreach ($ipPageList as $key => $value) {
$ipList[] = str_replace(' ','',getSubstr($value,"<a href=\"","\" target=\"_blank\""));
}
$tempArr = [];
foreach ($ipList as $key => $value) {
$str = curl($value);
if (empty($str))
continue;
$str = strip_tags($str,"<p><br>");
$str = getSubstr($str,"<p>","</p>");
$str = str_replace(["\n","\n\r","\r"], '', $str);
$arr = explode("<br />", $str);
$temp = null;
foreach ($arr as $key => $value) {
$temp['ip'] = getSubstr($value,'',':');
$temp['port'] = getSubstr($value,':','@');
$temp['area'] = getSubstr($value,'#','');
$tempArr[] = $temp;
}
}
return $tempArr;
}
你可能会用到字符串截取函数
function getSubstr($str, $leftStr, $rightStr) {
$left = empty($leftStr) ? 0 : strpos($str, $leftStr);
$right = empty($rightStr) ? strlen($str) : strpos($str, $rightStr,$left);
if($left < 0 or $right < $left) return '';
return substr($str, $left + strlen($leftStr), $right-$left-strlen($leftStr));
}
在上面的函数中用到的
-
strip_tags 函数剥去字符串中的 HTML、XML 以及 PHP 的标签。
这个函数还是比较重要的,因为我们从网页中获取都是HTML代码,我们不需要全部,我只要特定位置的字符串,先用这个函数保留div a标签的字符。 -
str_replace 函数以其他字符替换字符串中的一些字符(区分大小写)。
这里主要用来清除空格、换行、一些没用的字符。
经过这个两个函数和字符串截取函数的处理,现在这个str变量就只剩下
<a href="http://www.youdaili.net/Daili/http/4751.html" target="_blank">【HTTP代理】07月25号 http高匿/匿名在线代理ip服务器</a>2016-07-25<a href="http://www.youdaili.net/Daili/http/4748.html" target="_blank">【HTTP代理】07月25号 http游戏代理ip服务器</a>2016-07-25<a href="http://www.youdaili.net/Daili/http/4745.html" target="_blank">【HTTP代理】07月24号 最新高匿/匿名http代理ip</a>2016-07-24<a href="http://www.youdaili.net/Daili/http/4741.html" target="_blank">【HTTP代理】07月22号 国内外高匿http代理ip服务器</a>2016-07-22<a href="http://www.youdaili.net/Daili/http/4738.html" target="_blank">【HTTP代理】07月22号 在线代理http ip服务器</a>2016-07-22<a href="http://www.youdaili.net/Daili/http/4735.html" target="_blank">【HTTP代理】07月21号 http高匿名代理ip服务器地址</a>2016-07-21<a href="http://www.youdaili.net/Daili/http/4732.html" target="_blank">【HTTP代理】07月21号 http代理服务器ip地址</a>2016-07-21<a href="http://www.youdaili.net/Daili/http/4728.html" target="_blank">【HTTP代理】07月20号 http最新代理服务器ip地址</a>2016-07-20<a href="http://www.youdaili.net/Daili/http/4725.html" target="_blank">【HTTP代理】07月19号 最新http在线高匿/匿名代理ip</a>2016-07-19<a href="http://www.youdaili.net/Daili/http/4722.html" target="_blank">【HTTP代理】07月19号 http代理ip服务器地址</a>2016-07-19<a href="http://www.youdaili.net/Daili/http/4719.html" target="_blank">【HTTP代理】07月18号 免费高匿/匿名http代理ip</a>2016-07-18<a href="http://www.youdaili.net/Daili/http/4716.html" target="_blank">【HTTP代理】07月18号 http在线代理ip服务器</a>2016-07-18<a href="http://www.youdaili.net/Daili/http/4713.html" target="_blank">【HTTP代理】07月17号 http最新高匿/匿名代理ip</a>2016-07-17<a href="http://www.youdaili.net/Daili/http/4710.html" target="_blank">【HTTP代理】07月17号 在线代理最新http ip服务器</a>2016-07-17<a href="http://www.youdaili.net/Daili/http/4707.html" target="_blank">【HTTP代理】07月15号 最新高匿/匿名http代理ip</a>2016-07-15
这样的一个字符串,然后我们需要之中的链接,然后就用到
$ipPageList = explode('</a>', $str);
将字符串转换为数组,通过
</a>
然后就得到,这样一个数组
array(16) {
[0] => string(175) " <a href="http://www.youdaili.net/Daili/http/4751.html" target="_blank">【HTTP代理】07月25号 http高匿/匿名在线代理ip服务器"
[1] => string(135) "2016-07-25<a href="http://www.youdaili.net/Daili/http/4748.html" target="_blank">【HTTP代理】07月25号 http游戏代理ip服务器"
[2] => string(139) "2016-07-25<a href="http://www.youdaili.net/Daili/http/4745.html" target="_blank">【HTTP代理】07月24号 最新高匿/匿名http代理ip"
[3] => string(144) "2016-07-24<a href="http://www.youdaili.net/Daili/http/4741.html" target="_blank">【HTTP代理】07月22号 国内外高匿http代理ip服务器"
[4] => string(136) "2016-07-22<a href="http://www.youdaili.net/Daili/http/4738.html" target="_blank">【HTTP代理】07月22号 在线代理http ip服务器"
[5] => string(144) "2016-07-22<a href="http://www.youdaili.net/Daili/http/4735.html" target="_blank">【HTTP代理】07月21号 http高匿名代理ip服务器地址"
[6] => string(135) "2016-07-21<a href="http://www.youdaili.net/Daili/http/4732.html" target="_blank">【HTTP代理】07月21号 http代理服务器ip地址"
[7] => string(141) "2016-07-21<a href="http://www.youdaili.net/Daili/http/4728.html" target="_blank">【HTTP代理】07月20号 http最新代理服务器ip地址"
[8] => string(145) "2016-07-20<a href="http://www.youdaili.net/Daili/http/4725.html" target="_blank">【HTTP代理】07月19号 最新http在线高匿/匿名代理ip"
[9] => string(135) "2016-07-19<a href="http://www.youdaili.net/Daili/http/4722.html" target="_blank">【HTTP代理】07月19号 http代理ip服务器地址"
[10] => string(139) "2016-07-19<a href="http://www.youdaili.net/Daili/http/4719.html" target="_blank">【HTTP代理】07月18号 免费高匿/匿名http代理ip"
[11] => string(135) "2016-07-18<a href="http://www.youdaili.net/Daili/http/4716.html" target="_blank">【HTTP代理】07月18号 http在线代理ip服务器"
[12] => string(139) "2016-07-18<a href="http://www.youdaili.net/Daili/http/4713.html" target="_blank">【HTTP代理】07月17号 http最新高匿/匿名代理ip"
[13] => string(142) "2016-07-17<a href="http://www.youdaili.net/Daili/http/4710.html" target="_blank">【HTTP代理】07月17号 在线代理最新http ip服务器"
[14] => string(139) "2016-07-17<a href="http://www.youdaili.net/Daili/http/4707.html" target="_blank">【HTTP代理】07月15号 最新高匿/匿名http代理ip"
[15] => string(46) "2016-07-15 "
}
然后通过
$ipList = [];
foreach ($ipPageList as $key => $value) {
$ipList[] = str_replace(' ','',getSubstr($value,"<a href=\\\\"","\\\\" target=\\\\"_blank\\\\""));
}
将其转换为有用的URL数组,具体就不解释,留给读者思考。
array(16) {
[0] => string(44) "http://www.youdaili.net/Daili/http/4751.html"
[1] => string(44) "http://www.youdaili.net/Daili/http/4748.html"
[2] => string(44) "http://www.youdaili.net/Daili/http/4745.html"
[3] => string(44) "http://www.youdaili.net/Daili/http/4741.html"
[4] => string(44) "http://www.youdaili.net/Daili/http/4738.html"
[5] => string(44) "http://www.youdaili.net/Daili/http/4735.html"
[6] => string(44) "http://www.youdaili.net/Daili/http/4732.html"
[7] => string(44) "http://www.youdaili.net/Daili/http/4728.html"
[8] => string(44) "http://www.youdaili.net/Daili/http/4725.html"
[9] => string(44) "http://www.youdaili.net/Daili/http/4722.html"
[10] => string(44) "http://www.youdaili.net/Daili/http/4719.html"
[11] => string(44) "http://www.youdaili.net/Daili/http/4716.html"
[12] => string(44) "http://www.youdaili.net/Daili/http/4713.html"
[13] => string(44) "http://www.youdaili.net/Daili/http/4710.html"
[14] => string(44) "http://www.youdaili.net/Daili/http/4707.html"
[15] => string(1) "5"
}
然后用
$tempArr = [];
foreach ($ipList as $key => $value) {
$str = curl($value);
if (empty($str))
continue;
$str = strip_tags($str,"<p><br>");
$str = getSubstr($str,"<p>","</p>");
$str = str_replace(["\n","\n\r","\r"], '', $str);
$arr = explode("<br />", $str);
$temp = null;
foreach ($arr as $key => $value) {
$temp['ip'] = getSubstr($value,'',':');
$temp['port'] = getSubstr($value,':','@');
$temp['area'] = getSubstr($value,'#','');
$tempArr[] = $temp;
}
}
将每个页面的IP地址格式化,并存到tempArr数组中,tempArr数组,应该是这个样子(抓取时间有点长):
array(1667) {
[0] => array(3) {
["ip"] => string(12) "41.71.112.22"
["port"] => string(4) "3128"
["area"] => string(6) "南非"
}
[1] => array(3) {
["ip"] => string(13) "42.96.195.147"
["port"] => string(2) "82"
["area"] => string(48) "北京市 阿里巴巴(北京)科技有限公司"
}
[2] => array(3) {
["ip"] => string(13) "45.62.246.212"
["port"] => string(4) "8080"
["area"] => string(6) "美国"
}
...
然后就是把所有的IP存到数据库中,在tp5任意一个模块下的任意一个控制器创建
public function updateIp() {
ignore_user_abort();
set_time_limit(0);
$arr = getTodayIp();
if (empty($arr))
return false;
foreach ($arr as $key => $value) {
if ( empty($value['ip']) )
continue;
$temp = MIp::get(['ip' => $value['ip']]);
// 已存在或者其他进程在处理
if (!empty($temp))
continue;
$temp = new MIp();
$temp->save($value);
$connect_time = testIp($temp->ip,$temp->port);
if (!empty($connect_time) && $connect_time != 0) {
$temp->connect_time = $connect_time;
$temp->enabled = true;
$temp->save();
}
}
return true;
}
因为数据太多,我以后会教大家创建多个进程,同时去处理这些数据。
当然,你需要用到Ip表的结构
--
-- 表的结构 `ip`
--
CREATE TABLE IF NOT EXISTS `ip` (
`id` mediumint(9) NOT NULL,
`ip` varchar(256) DEFAULT NULL,
`port` int(11) DEFAULT '80',
`times` int(11) NOT NULL DEFAULT '0',
`connect_time` float DEFAULT NULL,
`area` varchar(1024) DEFAULT NULL,
`enabled` tinyint(1) NOT NULL DEFAULT '0'
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
--
-- Indexes for dumped tables
--
--
-- Indexes for table `ip`
--
ALTER TABLE `ip`
ADD PRIMARY KEY (`id`);
--
-- AUTO_INCREMENT for dumped tables
--
--
-- AUTO_INCREMENT for table `ip`
--
ALTER TABLE `ip`
MODIFY `id` mediumint(9) NOT NULL AUTO_INCREMENT;
当然,你也需要testIp函数,来测试代理IP的可用性。至少我的函数中用到了。
function testIp($ip, $port){
$curl = curl_init();
$url = 'http://cn.battleofballs.com/';
curl_setopt($curl, CURLOPT_URL, $url);
curl_setopt($curl, CURLOPT_TIMEOUT, 10);
$user_agent = "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:33.0) Gecko/20100101 Firefox/33.0";
curl_setopt ($curl, CURLOPT_USERAGENT, $user_agent);
curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, 2);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($curl,CURLOPT_PROXYTYPE,CURLAUTH_BASIC);
curl_setopt($curl, CURLOPT_PROXY, $ip);
curl_setopt($curl, CURLOPT_PROXYPORT, $port);
curl_setopt($curl, CURLOPT_PROXYTYPE, CURLPROXY_HTTP);
$str = curl_exec($curl);
$info = curl_getinfo($curl);
curl_close($curl);
return $info['connect_time'];
}
该函数返回时该代理IP访问球球大作战服务器用到的响应时间。
ignore_user_abort();
set_time_limit(0);
这段代码的意思就是,取消该程序的响应,让浏览器关闭后,也可以继续执行。当然,你可能需要修改php.ini 中的最大内存,可能用到的比较多。
然后就是curl函数,这个是自己封装的,有兴趣大家可以自己封装一个。
function curl($url,$time_out = 10) {
$curl = curl_init();
curl_setopt($curl, CURLOPT_URL, $url);
curl_setopt($curl, CURLOPT_TIMEOUT, $time_out);
$user_agent = "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:33.0) Gecko/20100101 Firefox/33.0";
curl_setopt ($curl, CURLOPT_USERAGENT, $user_agent);
curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, 2);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
$str = curl_exec($curl);
curl_close($curl);
return $str;
}
结语
其实到了这里php 网页爬虫已经介绍完了,差不过都是用curl获取到html代码,然后通过php str函数来处理。
下一节,我将要讲如何使用代理IP带模拟请求,增加棒棒糖。
当然,还会讲到PHP 计时任务,实现每天自动点击。
如果你感觉还不错,请不要忘了打赏、订阅、收藏、喜欢哦!!
有问题?
如果你在学习的过程中遇到问题?请联系
QQ:792598794
网友评论