文档章节

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

NateHuang
 NateHuang
发布于 09/29 10:56
字数 888
阅读 453
收藏 3

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

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并且校验可用性了。

© 著作权归作者所有

共有 人打赏支持
NateHuang
粉丝 19
博文 62
码字总数 29907
作品 0
深圳
后端工程师
私信 提问
代理IP爬取,计算,发放自动化系统

这学期有一门课叫《物联网与云计算》,于是我就做了一个大作业,实现的是对代理IP的爬取,计算推荐,发放给用户等任务的的自动化系统。由于代码比较多,有兴趣的可以到博主的GitHub上下载。 ...

郭璞
2016/10/05
0
0
一步步编写自己的PHP爬取代理IP项目(一)

第一章节主要给大家普及一下爬虫的概念以及相关的知识,让大家对后面的学习打下扎实的基础。如果你是有经验的开发者,完全可以跳过第一章进入第二章的学习了。 这个项目主要围绕两大核心点展...

NateHuang
09/14
0
0
一步步编写自己的PHP爬取代理IP项目(二)

这一章节我们正式开展我们的爬虫项目,首先我们先要知道哪个网站能获取到免费代理IP,目前比较火的有西刺代理,快代理等,这里我们拿西刺代理作为例子。 这里就是一个个免费的IP地址以及各自...

NateHuang
09/23
0
0
一步步编写自己的PHP爬取代理IP项目(二)

这一章节我们正式开展我们的爬虫项目,首先我们先要知道哪个网站能获取到免费代理IP,目前比较火的网站有西刺代理,快代理等,这里我们拿西刺代理作为例子。 西刺代理官网: http://www.xic...

NateHuang
09/18
0
0
爬虫代理 IP 池 - ProxyIpPool

ProxyIpPool 是一个爬虫代理 ip 池,主要用途爬取代理 ip ,然后将这些代理 ip 放入池子里(池子是某个数据结构的概念,比如我用的是队列)进行维护。 为什么需要维护呢?因为大多数代理 ip...

蛐蛐未加V
05/21
0
0

没有更多内容

加载失败,请刷新页面

加载更多

Qt那些事0.0.9

关于QThread,无F*k说的。文档说的差不多,更多的是看到很多人提到Qt开发者之一的“你TM的做错了(You're doing it wrong...)”,这位大哥2010年写的博客,下面评论很多,但主要还是集中在2...

Ev4n
33分钟前
1
0
constructor / destructor

_attribute__表示属性,是Clang提供的一种源码注释,方便开发者向编译器表达诉求,一般以__attribute__(*)的方式出现在代码中。为了方便使用,一些常用属性被定义成了宏,经常出现在系统头文...

HeroHY
34分钟前
1
0
大数据教程(7.6)shell脚本定时采集日志数据到hdfs

上一篇博客博主分享了hadoop内置rpc的使用案例,本节博主将为小伙伴们分享一个在实际生产中使用的日志搜集案例。前面的文章我们有讲到过用户点击流日志分析的流程,本节就是要完成这个分析流...

em_aaron
今天
1
0
wave和pcm互转

wav->pcm pcm->wav c#代码: using System;using System.Collections.Generic;using System.ComponentModel;using System.Data;using System.Drawing;using System.IO;using Sys......

whoisliang
今天
1
0
Win10:默认的图片打开应用,打开图片时速度明显很慢的解决办法

首先,我们随便地打开一张图片。然后,点击右上角的三个小点,最后点击弹出菜单最下面的“设置”。如下图: 在“设置”中找到下面的“人物”,把它关掉就好了。 原来,默认情况下,Win 10的图...

LivingInFHL
今天
3
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部