如何制作一个自己的IP代理池

开始前的准备

注:在开始完成这个项目之前,需要懂一些简单的爬虫知识和tkinter的界面相关知识,不过这些相关的内容,博主也会通过链接的方式,在其他文章内对其进行详细描述,手把手教你完成一个IP代理池。

第一步:IP代理池的功能实现

框架

一个IP代理池主要需要IP的获取以及IP的检测两大功能,以及一个方便的取用方式
获取:主要通过爬虫来获取大量的免费IP代理
检测:可以通过ping的方式,来对IP的可用性进行检测
取用:可以通过构建一个异步的web服务,以此能够用API的方式,极为方便的取用IP
因此我们可以先获得一个大概的代码框架:

class IP代理池(object):
    '''
    IP代理池
    用于获取代理IP以及维护代理IP池
    '''
    def __init__(self):
        pass

    def 代理爬取(self,num):
        pass

    def 代理检测(self):
        pass

    def 代理取用(self):
        pass


if __name__ == '__main__':
    IPAP = IP代理池()

IP的爬取

我们可以通过爬虫,来获取网上的一些代理。
这里我们仅主要介绍爬取一个网站,其余的大家可以自己去寻找并获取,以丰富自己的IP代理来源。
在代码的框架上进行修改,得到:

import time
import httpx
from lxml import etree

headers = {
    'User-Agent': "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/104.0.0.0 Safari/537.36"
}

class IP代理池(object):
    '''
    IP代理池
    '''
    def __init__(self):
        self.IPPool = []
        self.快代理链接 = "https://www.kuaidaili.com/free/"

    def 代理爬取(self,num):
        for i in range(1,num):
            url = self.快代理链接+"inha/"+str(i)
            res = httpx.get(url, headers=headers)
            if(res.status_code == 200):
                con = etree.HTML(res.text)
                ip_list = con.xpath('//*[@id="list"]/table/tbody/tr/td/text()')
                for i in range(len(ip_list)//8):
                    self.IPPool.append({"IP":ip_list[i*8+0],"Port":ip_list[i*8+1],"匿名度":ip_list[i*8+2],"类型":ip_list[i*8+3]})
                print(self.IPPool)
            time.sleep(1)

    def 代理检测(self):
        pass

    def 代理取用(self):
        pass

if __name__ == '__main__':
    IPAP = IP代理池()
    IPAP.代理爬取(2)

IP的检测

以下代码添加了IP的可用性检测模块,通过获取百度首页的方式,来判断代理是否可用,并筛选出反应速度在0.3s以上的代理,写入csv文件中

import time,os,csv
import httpx
from lxml import etree

headers = {
    'User-Agent': "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/104.0.0.0 Safari/537.36"
}

class IP代理池(object):
    '''
    IP代理池
    '''
    def __init__(self):
        self.IP池 = []
        self.可用IP = []
        self.快代理链接 = "https://www.kuaidaili.com/free/"

        # 如果存在IP代理池文件,则进行读取
        if(os.path.exists("IPPool.csv")):
            # 读取相关文档
            with open("IPPool.csv",'r') as csv_f:
                reader = csv.DictReader(csv_f)
                for cvs_row in reader:
                    self.IP池.append({'IP':cvs_row['IP'],'Port':cvs_row['Port'],'匿名度':cvs_row['匿名度'],'类型':cvs_row['类型']})

    def 代理爬取(self,num):
        for i in range(1,num+1):
            url = self.快代理链接+"inha/"+str(i)
            res = httpx.get(url, headers=headers)
            if(res.status_code == 200):
                con = etree.HTML(res.text)
                ip_list = con.xpath('//*[@id="list"]/table/tbody/tr/td/text()')
                for i in range(len(ip_list)//8):
                    ipcon = {"IP":ip_list[i*8+0],"Port":ip_list[i*8+1],"匿名度":ip_list[i*8+2],"类型":ip_list[i*8+3]}
                    if(not ipcon in self.IP池):
                        self.IP池.append(ipcon)
                        print("添加IP代理:"+ipcon["IP"]+":"+ipcon["Port"])
                    else:
                        print("IP代理:"+ipcon["IP"]+":"+ipcon["Port"]+"已存在")
            time.sleep(1)

    def 代理检测(self):
        for each in self.IP池:
            proxies = {each["类型"]+"://":each["类型"]+"://"+each["IP"]+":"+each["Port"]}
            res = httpx.get("https://www.baidu.com/", headers=headers, proxies=proxies, timeout=0.3)
            if(res.status_code == 200):
                if(not each in self.可用IP):
                    self.可用IP.append(each)
                    print("IP代理:"+each["IP"]+":"+each["Port"]+"可使用")
                else:
                    print("IP代理:"+each["IP"]+":"+each["Port"]+"已存在")
            else:
                print("IP代理:"+each["IP"]+":"+each["Port"]+"无效")

        with open("IPPool.csv",'w',newline='') as csv_f:
            write=csv.writer(csv_f)
            # 写入头
            row=['IP','Port','匿名度','类型']
            write.writerow(row)
            for each in self.可用IP:
                # 写入数据
                row=[each["IP"],each["Port"],each["匿名度"],each["类型"]]
                write.writerow(row)
            print("代理IP写入完毕!")

    def 代理取用(self):
        pass

if __name__ == '__main__':
    IPAP = IP代理池()
    index = input('1.爬取代理\n2.检测代理\n3.取用代理\n请选择:')
    while(True):
        if(index == '1'):
            IPAP.代理爬取(2)
            IPAP.代理检测()
        elif(index == '2'):
            IPAP.代理检测()
        elif(index == '3'):
            IPAP.代理取用()

IP的取用

IP的取用部分本来也是想要封装在类里的,但是Sanic似乎必须运行在主线程,暂时一下子没有找到什么解决方法,能力有限,也就先这样用了。
主要是希望能够通过API的方式进行调用,获取IP,当前是通过get的方式,来随机获取IP,后续也可以进行进一步优化,通过post请求,按照指定方式来获取指定数量的IP。

import time,os,csv,random
import httpx
from sanic import Sanic
from lxml import etree
import threading
from sanic.response import json
headers = {
    'User-Agent': "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/104.0.0.0 Safari/537.36"
}

class IP代理池(object):
    '''
    IP代理池
    '''
    def __init__(self):
        self.IP池 = []
        self.可用IP = []
        self.快代理链接 = "https://www.kuaidaili.com/free/"
        
        # 如果存在IP代理池文件,则进行读取
        if(os.path.exists("IPPool.csv")):
            # 读取相关文档
            with open("IPPool.csv",'r') as csv_f:
                reader = csv.DictReader(csv_f)
                for cvs_row in reader:
                    self.IP池.append({'IP':cvs_row['IP'],'Port':cvs_row['Port'],'匿名度':cvs_row['匿名度'],'类型':cvs_row['类型']})

    def 代理爬取(self,num):
        for i in range(num):
            url = self.快代理链接+"inha/"+str(i+1)
            try:
                res = httpx.get(url, headers=headers)
            except:
                print("爬取超时")
            time.sleep(1)
            if(res.status_code == 200):
                con = etree.HTML(res.text)
                ip_list = con.xpath('//*[@id="list"]/table/tbody/tr/td/text()')
                for i in range(len(ip_list)//8):
                    ipcon = {"IP":ip_list[i*8+0],"Port":ip_list[i*8+1],"匿名度":ip_list[i*8+2],"类型":ip_list[i*8+3]}
                    if(not (ipcon in self.IP池)):
                        self.IP池.append(ipcon)
                        print("添加IP代理:"+ipcon["IP"]+":"+ipcon["Port"])
                    else:
                        print("IP代理:"+ipcon["IP"]+":"+ipcon["Port"]+"已存在")
            
    def 代理检测(self):
        for each in self.IP池:
            proxies = {each["类型"]+"://":each["类型"]+"://"+each["IP"]+":"+each["Port"]}
            try:
                res = httpx.get("https://www.baidu.com/", headers=headers, proxies=proxies, timeout=0.3)
            except:
                print("检测超时,检测未通过")
            if(res.status_code == 200):
                if(not each in self.可用IP):
                    self.可用IP.append(each)
                    print("IP代理:"+each["IP"]+":"+each["Port"]+"可使用")
                else:
                    print("IP代理:"+each["IP"]+":"+each["Port"]+"已存在")
            else:
                print("IP代理:"+each["IP"]+":"+each["Port"]+"无效")

        with open("IPPool.csv",'w',newline='') as csv_f:
            write=csv.writer(csv_f)
            # 写入头
            row=['IP','Port','匿名度','类型']
            write.writerow(row)
            for each in self.可用IP:
                # 写入数据
                row=[each["IP"],each["Port"],each["匿名度"],each["类型"]]
                write.writerow(row)
            print("代理IP写入完毕!")

IPAP = IP代理池()
app = Sanic("IPPoll")
@app.route("/")
async def IP代理取用(request):
    num = random.randint(0,len(IPAP.IP池)-1)
    return json({
        'IP': IPAP.IP池[num]['IP'],
        'Port': IPAP.IP池[num]['Port'],
        'Type': IPAP.IP池[num]['类型']
            })

def IP爬取():
    index = input('1.爬取代理\n2.检测代理\n请选择:\n')
    while(True):
        if(index == '1'):
            IPAP.代理爬取(50)
            IPAP.代理检测()
        elif(index == '2'):
            IPAP.代理检测()

if __name__ == '__main__':
    threading.Thread(target=IP爬取).start()
    app.run(host="localhost", port=8000)
    

在这里插入图片描述

使用方式:
直接访问 “http://localhost:8000/” 即可。

这样一来,整个的基本盘也就完成了,后续当然还可以进行很多的优化,这些就交给大家自己去尝试了。
如:
IP获取的各种方式
IP爬取的速度
代理IP获取的来源
定时的IP获取
或者如果需要UI界面的话,也可以进行添加
等等等等……

最后:千万记得,点赞,关注,收藏哦~
有什么其他的问题也可以在评论区询问,作者后面有时间也会把优化完的IP代理池也发一下,一切以使用更方便为目的。

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

水水不水啊

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值