一步步编写自己的PHP爬取代理IP项目(三)

上一章节我们讲完了自动加载,现在我们正式进入爬虫核心代码的编写中,首先我们需要先看看整个目录

config.php        这个是我们的配置文件加载文件

ProxyPool.php  这个是爬虫的核心处理文件

Queue.php       这个是队列操作的处理文件

Requests.php   这个是发起请求的处理文件

然后我们在回忆一下入口文件的代码

<?php
require_once __DIR__ . '/autoloader.php';
require_once __DIR__ . '/vendor/autoload.php';

use ProxyPool\core\ProxyPool;

$proxy = new ProxyPool();
$proxy->run();

通过这里可以看到我们使用了core里面ProxyPool的run方法,先来看看ProxyPool的内容吧

<?php

use ProxyPool\core\Requests;  //HTTP请求文件
use ProxyPool\core\Queue;   //队列操作文件

class ProxyPool
{
    private $redis;
    private $httpClient;    
    private $queueObj;
        
    function __construct()
    {
        $redis = new \Redis();
        $redis->connect(config("database.redis_host"), config("database.redis_port"));
        $this->redis = $redis;$this->httpClient = new Requests(['timeout' => 10]);
        $this->queueObj = new Queue();
    }
        
    public function run()
    { 
        echo "start to spider ip...." . PHP_EOL;
        $ip_arr = $this->get_ip(); //获取IP的具体方法
        echo "select IP num: " . count($ip_arr) . PHP_EOL;
            
        echo "start to check ip...." . PHP_EOL;
        $this->check_ip($ip_arr);  //验证IP可用性的方法
        $ip_pool = $this->redis->smembers('ip_pool');  //读取redis中的ip
        echo "end check ip...." . PHP_EOL;  
               
        print_r($ip_pool);  //输出ip数组
        die;
    }
}

其中get_ip方法会爬取两个网站的IP

//获取各大网站代理IP
private function get_ip()
{
    $ip_arr = [];
    $ip_arr = $this->get_xici_ip($ip_arr);      //西刺代理
    $ip_arr = $this->get_kuaidaili_ip($ip_arr); //快代理
    return $ip_arr;
}

我们先来来看看西刺代理的爬取

private function get_xici_ip($ip_arr)
{
    for ($i = 1; $i <= config('spider.page_num'); $i++) 
    {
        list($infoRes, $msg) = $this->httpClient ->request('GET','http://www.xicidaili.com/nn/'.$i,[]);
        if (!$infoRes) 
        {
            print_r($msg);  //输出错误信息
            exit();
        }
        $infoContent = $infoRes->getBody();
        $this->convert_encoding($infoContent);
        preg_match_all('/<tr.*>[\s\S]*?<td class="country">[\s\S]*?<\/td>[\s\S]*?<td>(.*?)<\/td>[\s\S]*?<td>(.*?)<\/td>/', $infoContent, $match);
        
        $host_arr = $match[1];
        $port_arr = $match[2];
        foreach ($host_arr as $key => $value) 
        {
            $ip_arr[] = $host_arr[$key].":".$port_arr[$key];
        }
    }
    return $ip_arr;
}

这个方法里面,我们首先使用 config('spider.page_num') 这个方法读取了配置文件里面定义的爬取页数,我这里定义的是3页,然后我们打开西刺代理的网站,会发现域名是

http://www.xicidaili.com/nn/XX      这个XX是第几页,第一页就是1,第二页就是2,以此类推

所以我们在代码里面循环访问了三次网站,获取到网页的返回值,然后用正则匹配html去获取里面的地址和端口号(具体html元素可以在网站右键点击审查元素查看)

preg_match_all('/<tr.*>[\s\S]*?<td class="country">[\s\S]*?<\/td>[\s\S]*?<td>(.*?)<\/td>[\s\S]*?<td>(.*?)<\/td>/', $infoContent, $match);

然后经过一些处理,将获取到的IP返回。这就是get_xici_ip这个方法做的事情,它就是负责爬取IP。

然后我们来看看

//检测IP可用性
private function check_ip($ip_arr)
{
    $this->queueObj = $this->queueObj->arr2queue($ip_arr);
    $queue = $this->queueObj->getQueue();
    foreach ($queue as $key => $value) 
    {
        //用百度网和腾讯网测试IP地址的可用性
        for ($i=0; $i < config('spider.examine_round'); $i++) 
        {
            $response = $this->httpClient->test_request('GET','https://www.baidu.com', ['proxy' => 'https://'.$value]);
            if (!$response) 
            {
                $response = $this->httpClient->test_request('GET','http://www.qq.com', ['proxy' => 'http://'.$value]);
                if ($response && $response->getStatusCode() == 200) 
                {
                    break;
                }
            }
            else if($response->getStatusCode() == 200)
            {
                break;
            }
        }
        //将结果存入redis   
        if ($response && $response->getStatusCode() == 200) 
        {
            $this->set_ip2redis($value);   
        }    
        else{
            echo $value . " error...  ". PHP_EOL;    
        }
    }
}

这里我们使用了https的百度和http的qq来检测,如果成功访问就把这个IP插入redis中。

这样我们就能做到爬取IP并且校验可用性了。

优秀的个人博客,低调大师

微信关注我们

原文链接:https://my.oschina.net/hjchhx/blog/2221364

转载内容版权归作者及来源网站所有!

低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。

相关文章

发表评论

资源下载

更多资源
优质分享Android(本站安卓app)

优质分享Android(本站安卓app)

近一个月的开发和优化,本站点的第一个app全新上线。该app采用极致压缩,本体才4.36MB。系统里面做了大量数据访问、缓存优化。方便用户在手机上查看文章。后续会推出HarmonyOS的适配版本。

Mario,低调大师唯一一个Java游戏作品

Mario,低调大师唯一一个Java游戏作品

马里奥是站在游戏界顶峰的超人气多面角色。马里奥靠吃蘑菇成长,特征是大鼻子、头戴帽子、身穿背带裤,还留着胡子。与他的双胞胎兄弟路易基一起,长年担任任天堂的招牌角色。

Eclipse(集成开发环境)

Eclipse(集成开发环境)

Eclipse 是一个开放源代码的、基于Java的可扩展开发平台。就其本身而言,它只是一个框架和一组服务,用于通过插件组件构建开发环境。幸运的是,Eclipse 附带了一个标准的插件集,包括Java开发工具(Java Development Kit,JDK)。

Java Development Kit(Java开发工具)

Java Development Kit(Java开发工具)

JDK是 Java 语言的软件开发工具包,主要用于移动设备、嵌入式设备上的java应用程序。JDK是整个java开发的核心,它包含了JAVA的运行环境(JVM+Java系统类库)和JAVA工具。