前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >一步步编写自己的PHP爬取代理IP项目(三)

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

作者头像
NateHuang
发布2019-03-12 17:26:59
7220
发布2019-03-12 17:26:59
举报
文章被收录于专栏:开发经验记录

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

config.php        这个是我们的配置文件加载文件 ProxyPool.php  这个是爬虫的核心处理文件 Queue.php       这个是队列操作的处理文件 Requests.php   这个是发起请求的处理文件

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

代码语言:javascript
复制
<?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的内容吧

代码语言:javascript
复制
<?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

代码语言:javascript
复制
//获取各大网站代理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;
}

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

代码语言:javascript
复制
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元素可以在网站右键点击审查元素查看)

代码语言:javascript
复制
 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。

然后我们来看看

代码语言:javascript
复制
//检测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并且校验可用性了。

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2018/09/29 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
云数据库 Redis
腾讯云数据库 Redis(TencentDB for Redis)是腾讯云打造的兼容 Redis 协议的缓存和存储服务。丰富的数据结构能帮助您完成不同类型的业务场景开发。支持主从热备,提供自动容灾切换、数据备份、故障迁移、实例监控、在线扩容、数据回档等全套的数据库服务。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档