FreeIP池搭建


前言

用来采集IP的网址
免费IP的是最拉跨的,要买的话推荐是买它家的隧道代理

一、认识代理

当你访问网站过于频繁的时候,可能会触发反爬机制然后你的IP就被封了,访问不了网站了,怎么办?
换IP而且控制访问频率

import  requests
UA = {
    "User-Agent":"*****"
url ="*****"
dict ={
    "http":"http://120.234.203.171:9002", #ip:端口  =>   120.234.203.171:9002
    "https":"https://120.234.203.171:9002"
}
#代理ip使用注意: 需要根据你要访问的网址来确定代理ip能否访问 如果你的网址为https 而代理只支持http代码可能会报错
#代理需要知道其组成为 ip:端口
# resp = requests.get(url,headers = UA)  #未使用代理ip
resp =requests.get(url,proxies = dict,headers = UA)  #使用代理
#代理属于灰色产业   可以溯源   一般免费的都不好用卡的死
resp.encoding = 'utf-8'
print(resp.text)

二、我需要很多IP怎么办?

弄一个代理IP池,思路是从很多提供(多个)免费代理的网站上提取免费IP存到你的数据库(去重)里,然后筛选处好用的IP供自己使用。
数据库选择:Redis 数据结构:zset (有序集合)
思路:多进程+爬取ip+验证Ip+提供ip+模块化编程
在这里插入图片描述

python 模块化编程知识:
比如两个py文件test1,test2。
可以在test2中import test1进行模块导入,导入时会为test1开辟内存空间,并且在该内存空间中执行test1文件。
如果不想执行test1文件而只是想导入test1中的函数可以通过判断语句来实现

#单独运行test1文件时__name__的值为'__main__'
#作为模块导入时__name__的值为'__test1__'
if __name__ == '__main__'

准备工作:
连接上Redis
新建文件
在这里插入图片描述

参数文件

HOST = "***"
#后台端口
PORT = ****
#App名字
APPNAME = "ip"
#数据库端口
PORT2 =***
#密码
PASS = "****"
#数据库号
DBBH= 1

0.对Redis数据库的通用操作/模块化编程的益处

定义一个类ProyxRedis,在新建对象时自动连接Redis数据库。
实现添加Ip且不重复添加。
对可用IP给满分,不可用减分,分值小于0的IP进行删除。
获取所有IP
获取单个IP(优先可以使用的IP)

import redis
import random
#从Setting中导入参数
from Setting import *

class ProyxRedis:
    #实现类的时候必定执行__init__
    def __init__(self):
        self.red = redis.Redis(
            port=PORT2 , #端口号
            host =HOST, #ip地址
            password=PASS, #密码
            db=DBBH, #数据库编号
            decode_responses=True #对返回字节自动解码
        )


    #添加Ip
    def add_ip(self,ip):
        if not self.red.zscore("proxy",ip):
            self.red.zadd("proxy",{ip:10})
            print("采集到新ip"+ip)
        else:
            print(ip+"已经存在了")

    #获取所有Ip
    def get_allIP(self):
        return self.red.zrange("proxy",0,-1)

    #ip分数拉满
    def set_maxip(self,ip):
        self.red.zadd("proxy",{ip:100})
        print(ip+"可用,分数拉满")

    #扣分
    def desc_score(self,ip):
        s = self.red.zscore("proxy",ip)
        if s and s>0:
            self.red.zincrby("proxy",-1,ip)
            print(ip + "不可用,分数-1")
        else:
            self.red.zrem("proxy",ip)
            print(ip + "不可用且分数过低,进行删除")
    #拿一个Ip来用
    def get_ip(self):
       #拿100分到100分的所有ip
        ips = self.red.zrange("proxy",100,100,0,-1)
        if ips:
            return random.choice(ips)
        else:
            ipst=self.red.zrange("proxy",11,99,0,-1)
            if ipst:
                return random.choice(ipst)
            else:
                print("无可用ip")

收集IP

import requests
from lxml import etree
import time
#导入模块
import proxy_redis
#实例化类
red = proxy_redis.ProyxRedis()
UA = {
    "User-Agent":"***"
}
def get_kip():

def get_kxxip(i):

def run():
    i=1
    while 1:
        try:
            get_kip()
            get_kxxip(i)
            i=i+1
        except:
            print("崩了")
        time.sleep(20)

if __name__ == '__main__':
    run()

协程验证IP可用性

import time

import proxy_redis
import asyncio
import aiohttp

async def verify(i,sem,red):
    #响应等待时间上限
    time2=aiohttp.ClientTimeout(total=10)
    try:
        async with aiohttp.ClientSession() as session:
            async with session.get("http://www.***.com",proxy=i,timeout=time2) as resp:
                #这里要获取page_source是因为网站可能请求超时
                page_source=await resp.text()
                if resp.status in [200,302]:
                    red.set_maxip(i)
                    print(i+"可用"+"分值拉满")
                else:
                    red.desc_score(i)
                    print(i + "不可用" + "分值减小")
    except Exception as e:
        print("长时间无应答",e)
        red.desc_score(i)
        print(i + "不可用" + "分值减小")

async def main(red):
    all_ip=red.get_allIP()
    task = []
    sem =asyncio.Semaphore(30) #控制并发量
    for i in all_ip:
        task.append(asyncio.create_task(verify(i,sem,red)))
    if task:  #保证task不为空
        await asyncio.wait(task)

def run():
    red = proxy_redis.ProyxRedis()
    time.sleep(10) #多进程情况下应优先采集数据故sleep(10)让ip_collection先获取部分数据,
    #防止task为空
    while 1:
        try:
            asyncio.run(main(red))
            time.sleep(30)
        except Exception as e:
            print("检验出错",e)
            time.sleep(30)

if __name__ == '__main__':
    run()

提供接口

import proxy_redis  #类

from sanic import Sanic, json
from sanic_cors import CORS
import multiprocessing

from  Setting import * #参数

app = Sanic(APPNAME) #app名字
CORS(app) #跨域
red = proxy_redis.ProyxRedis()

@app.route("/get_proxy") #打开谷歌输入 网址/get_proxy
def qip(req):
    ip = red.get_ip()
    return json({"ip": ip})  #返回IP

#不建议用默认端口号,因为端口号6379被占用了。这个端口号一般用于Redis服务,默认情况下是被Redis占用的。你需要将端口号修改为其他未被占用的端口。
def run():
    if not multiprocessing.get_start_method():
        multiprocessing.set_start_method("spawn")
    app.run(host=HOST, port=PORT)  #运行app提供IP

if __name__ == '__main__':
    run()

多进程任务执行

from  ip_api import run as api_run
from ip_verify import run as verify_run
from ip_collection import run as coll_run
from multiprocessing import Process


def run():
    p1 = Process(target=api_run)
    p2 = Process(target=verify_run)
    p3=Process(target=coll_run)
    p1.start() #提供IP接口
    p3.start() #收集IP
    p2.start() #验证IP


if __name__ == '__main__':
    run()

    # 在后台运行python来采集Ip
    #在终端进入当前Py文件的目录
    #dir命令查看当前路径下的文件有哪些
    #执行RUN.py命令:
     #python RUN.py

测试效果

import requests
UA = {
    "User-Agent":"***"
}

def get_proxy():
    url = "http://****/get_proxy"
    resp = requests.get(url,headers = UA)
    dic = resp.json()
    proxy={
        "http":dic["ip"][0],
        "https":dic["ip"][0]
    }
    print(proxy)
    # 网页可能会重新定向到https,但是我的代理Ip只能使用http访问,所以https也用http试试
    #{'http': 'http://121.8.215.106:9797', 'https': 'http://121.8.215.106:9797'}
    return proxy


url = "http://www.***.com"

#实际效果看代理池中的ip
resp = requests.get(url,headers = UA,proxies=get_proxy())
print(resp.text)
请为下面的代码写备注,解释每一个参数的意思是什么: 00:00:00 [cmd:DATA,Q:M00101gAAP88E2QUio0A,tid:AQAAfwCXB13_PBNkz8aNAA--.62429S2,ip:192.168.166.17,ClientIp:192.168.166.17,FreeIP:0,FreeIPFlag:0,ssl:0,CmProtocol:0,SysWhitelist:0,origip:,xmailer:,Sender:,SenderEmail:,Local:0,FromDN:,org_id:,org_unit_id:@,HdrFrom:System),ClientPort:55576,ipsmtpspamoutcnt:0(-1) 0(-1),BlackUser:0,Rcpt:malp@smu.edu.cn;,RcptHandle:,lrcptcnt:1,rrcptcnt:0,LmtpRcpt:,LmtpRcptCnt:0,DataRuleID:0,DataRuleName:,DataPolicyID:1,Size:2602,Reputation:,BM:0,BMRespond:,Score:7.10,CntRuleID:0,CntRuleName:,PolicyID:0,AttachCnt:0,AttachFngCnt:0,BlackURL:0,GlobalSkipRBLIP:0,PassGlobalGrayList:0,ApiGrayIP:0,GrayList:0,PassGrayList:0,GrayListDelay:0,PassGrayListDelay:0,DataFngCnt:0,RcptFngCnt:0,DataSFngCnt:0,RcptSFngCnt:0,DataGifFngCnt:0,RcptGifFngCnt:0,GifShortLineCnt:0,DataJpgFngCnt:0,RcptJpgFngCnt:0,JpgSVMSpam:0,JpgSVMProb:0.00,STextSVMSpam:0,STextSVMProb:0.00,DkimVerifyResult:3,DkimSigResults:,SpamFng:0,HoneyPot:0,subject:Undelivered Mail Returned to Sender,SubjectCnt:2132,Handle:4,Respond:553 Requested action not taken\: NULL sender is not allowed\r\n,Result:Reject,DebugInfo:empty mailfrom is prohibited,DebugContext:,Delivered:0,Async:0,HdrDate:1678982401,Eval:BAYES_80;BM_PASS;CMD_CNT_00_10;CUR_CONN_00_01;DKIM_NEUTRAL;DMARC_NON_ALIGNED;DOMAIN_QUARTER_CNT_00_05;DOMAIN_QUARTER_RCPT_CNT_00_10;DOMAIN_TODAY_CNT_00_10;DOMAIN_TODAY_RCPT_CNT_00_10;FAKE_BOUNCE_MESSAGE;GET_ERROR_HEADER_FIELD;HTML_MIME_NO_HTML_TAG;IP_QUARTER_CNT_01_02;IP_TODAY_CNT_50_100;JPG_SVM_PROB_00_10;PTR_NO;REPUTATION_NULL;RUSER_QUARTER_CNT_00_05;RUSER_QUARTER_RCPT_CNT_00_10;RUSER_TODAY_CNT_00_10;RUSER_TODAY_RCPT_CNT_00_10;SPF_NONE;STEXT_SVM_PROB_00_10;SUBJECT_CNT_2000_3000;TEXT_HTML_CNT_00_01;TEXT_PLAIN_CNT_01_03;TO_CC_BCC_CNT_00_02;URLREP_NULL;USER_SEND_INTERVAL_00_05,Content:InqmfXjmfXjA-nxDTs0mTbjWhVFAasAD3V7D-nEWSbjA-sCvo9Gp3Z0danEl3svLoDAO17mYYZADfZEXfBkDSU==,optime:606,delaytime:0,errinfo:,ttime:1,tsize:2611]
07-25
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

秋刀鱼_(:з」∠)_别急

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

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

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

打赏作者

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

抵扣说明:

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

余额充值