通过Python利用ADSL服务器和tinyproxy构建数据自己的动态代理IP池,用django+redis做web服务,提供IP接口
应公司业务需求需要在一些地方使用代理,要求连通率高,速度快,最主要的还要便宜,对比多家供应商后,最后还是决定自购拨号服务搭建代理IP池。
需要配置:1.一台或多台adsl服务器(用以提供IP,可网上购买,通过ssh同域名连接)2.一台正常固定IP服务器拥来搭建IP代理池。(统一配置:python3.5以上环境)
具体配置:
1.在ADSL服务器上部署tinyporxy服务, 可以直接yum安装(yum -y install tinyproxy);
默认配置文件 /etc/tinyproxy/tinyproxy.conf,可执行文件 /usr/sbin/tinyproxy;
需要将配置文件中的第210行 Allow 127.0.0.1 注释掉,23行 Port 8888 改为自己喜欢的端口(请注意在防火墙中将该端口开启);
这样子代理服务器就配置好了,可以直接通过 tinyproxy 启动服务,killall tinyproxy 关闭服务;
ADSL服务器需要通过 pppoe 来进行拨号,需要有宽带账号,如果是直接购买的拨号服务器,一般都会配置好(我的就是);
拨号命令:pppoe-start (进行拨号),pppoe-stop(断开拨号连接),pppoe-status(查看当前拨号状态);
2. 用来做代理池的服务器需要安装 redis,python3安装django,redis包
(之所以使用django是因为之前的爬虫分发服务是基于Django实现的,所以现在只是在上面增加个代理池的);
代码逻辑:
之所以需要设置代理池,是因为我们所需要的代理IP就是拨号服务器不断变化的那个个IP,
代理池web服务最少应该提供三个接口:
1.在重新拨号(切换IP)前请求一次的接口 ,用来清除此台拨号服务器服务器上次提交的IP,
2.重新拨号成功后(成功切换IP)提交IP的接口,
3.用来提取IP的接口,
主要操作 redis 的 hash 类型(用来唯一标识一台拨号服务器和其提交的IP), 链表类型(用来做IP池)
为了应对本身业务需求和最大化利用代理IP增加:
4.提取到IP使用过后重新放入代理池的接口
根据测试得出单个代理对请求速度影响较小的最大并发数,链表内放入代理 IP*最大并发数 (我这里设置为22)
又另外增加redis 集合类型(防止提取到不可用IP)
代码部分:
代理池端部分代码,如需使用,可以直接引入到Django视图中,自己构建4个API接口,分别调用四个方法。
import redisclass ProxyPool:def __init__(self):self.pool = redis.ConnectionPool(host='127.0.0.1',port=6379, db=7)#删除旧的IPdef update_del(self,only):try:conn = redis.Redis(connection_pool=self.pool)#哈希表中取出本次提供IP服务器在上一次提供的IPoldIP = conn.hget('Onlypool',only)if oldIP:#删除唯一标识conn.hdel('Onlypool',only)oldIP = str(oldIP,encoding='utf-8')#在集合中删除上次的IPconn.srem('IPset',oldIP)conn.lrem('IPpool',oldIP,0)return {'state':1,'message':'操作成功'}else:return {'state':2,'message':'未找到该机器'}except Exception as e:return {'state':0,'message':'操作失败--'+str(e)}#增加新的IPdef update_put(self,ip,only):try:conn = redis.Redis(connection_pool=self.pool)#判断此IP是否已经存在于池中state = conn.sismember('IPset', ip)if state:return {'state': 0, 'message': '此IP以存在于池中'}#以本次提供IP的唯一标识做键写入哈希表中conn.hset('Onlypool',only,ip)# 在集合中添加本次IPconn.sadd('IPset', ip)proxy = [ip] * 22#放入IP池中for i in proxy:conn.rpush('IPpool',i)return {'state':1,'message':'操作成功'}except Exception as e:return {'state':0,'message':'操作失败--'+ str(e)}#获取指定数量的有效IPdef getIP(self,num=1):try:conn = redis.Redis(connection_pool=self.pool)ipList = []for i in range(num):while True:ip = conn.lpop('IPpool')if ip:state = conn.sismember('IPset', ip)if state:ip = str(ip,encoding='utf-8')ipList.append(ip)break#数量不足时,放弃提取,并把已经提取的重新放回池中else:leninfor = len(ipList)for ip in ipList:conn.rpush('IPpool', ip)return {'state': 0, 'message': 'IP不足,可用长度为:{0}'.format(leninfor)}return {'state': 1, 'ipList':ipList,'message':'操作成功'}except Exception as e:return {'state': 0, 'message': '操作失败--' + str(e)}#把使用过后的IP重新塞入池中def putIP(self,ipList):try:conn = redis.Redis(connection_pool=self.pool)for ip in ipList:# 判断是否存在于集合中,存在即有效,不存在则放弃存入state = conn.sismember('IPset', ip)if state:conn.rpush('IPpool',ip)return {'state':1,'message':'操作成功'}except Exception as e:return {'state': 0, 'message': '操作失败--' + str(e)}if __name__ == '__main__':pass
拨号服务器端代码,这里设置没隔三分钟左右重新更换IP, 这里的机器唯一标识为图简单,自己设置
#!/usr/bin/python3
import re,time,os,requests,json,datetime,random
#唯一标识
only = 'only1'
#切换IP,重启代理服务
def changeIP():os.system('pppoe-stop')time.sleep(3)os.popen('service tinyproxy stop')os.popen('pppoe-start')time.sleep(7)os.popen('service tinyproxy start')
#取出当前IP
def extractIP():infor = os.popen('pppoe-status').read()try:ip = re.search('(\d+\.\d+\.\d+\.\d+)',infor).group(1)return ipexcept:return False
#删除旧的IP
def updateDel():url = 'http://***.**.**.***:8000/proxy/updateDel?&only={0}'.format(only)for i in range(3):try:res = requests.get(url,timeout=3)infor = json.loads(res.text)if infor['state']:breakelse:continueexcept Exception as e:continue
#提交新的IP
def updatePut(ip):ip = ip+':'+'8888'url = 'http://***.**.**.***:8000/proxy/updatePut?ip={0}&only={1}'.format(ip,only)for i in range(3):try:res = requests.get(url,timeout=3)infor = json.loads(res.text)if infor['state']:breakelse:continueexcept Exception as e:continueif __name__ == '__main__':a = 1while True:if a==2:time.sleep(random.randrange(170,230))a=2updateDel()#删除IP后等待2秒在执行重新拨号,为防止池中取出不可用代理time.sleep(2)#print('已经删除旧IP')while True:changeIP()ip = extractIP()if ip:breakupdatePut(ip)#print('已经更新IP')
可能需要到的:
安装tinyproxy失败,需要centos更新yum源:yum install epel-release
killall无效,需要安装psmisc: yum install psmisc
centos7防火墙端口添加
firewall-cmd --zone=public --add-port=8888/tcp --permanent
重新载入
firewall-cmd --reload
最新:https://blog.csdn.net/MeteorCountry/article/details/82729027
通过Python利用ADSL服务器和tinyproxy构建数据自己的动态代理IP池,用django+redis做web服务,提供IP接口相关推荐
- 通过Python利用ADSL服务器和tinyproxy构建数据自己的动态代理IP池,用django+redis做web服务 (优化版)
代理池初始版:https://blog.csdn.net/MeteorCountry/article/details/82085238 上一篇文章中所搭建的代理池在使用过程中出现了点小问题,代理池中莫 ...
- python导入excel模块_Excel到python第一章python利用pandas和numpy模块导入数据
原博文 2019-08-29 21:18 − import numpy as np import pandas as pd # 导入数据 # 读取csv数据 df = pd.read_csv(open ...
- 【ValueError: could not convert string to float: ‘young‘】python利用pandas对string类型的数据序列化
项目场景: 利用sklearn库构建决策树,使用sklearn.tree.DecisionTreeClassifier()提供的方法----fit()决策树可视化的时候,我们看到程序报错了 问题描述 ...
- Python利用xlsxwriter实现对Excel写入数据的样式调整(字体,居中等)
声明:参考大佬文章 参考网上资料发现很少有用xlsxwriter实现用Python对Excel写入数据的同时进行字体样式调整操作的,因为我用的也是xlsxwriter,所以查找总结了一个用xlsxwr ...
- python使用redis队列_【Python】python使用redis做队列服务
系统中引入消息队列机制是对系统一个非常大的改善.例如一个web系统中,用户做了某项操作后需要发送邮件通知到用户邮箱中.你可以使用同步方式让用户等待邮件发送完成后反馈给用户,但是这样可能会因为网络的不确 ...
- python如何对接api接口_Python做Web API对接---查看接口
3:Cookies(用户验证,基于HTTP协议的)之前的文章已经说了如何通过API登录验证,这里就不多说了,需要看的话,点击链接查看即可:https://club.kingdee.com/forum. ...
- python ip动态代理_给自己的爬虫做一个简单的动态代理池
使用代理服务器一直是爬虫防BAN最有效的手段,但网上的免费代理往往质量很低,大部分代理完全不能使用,剩下能用的代理很多也只有几分钟的寿命,没法直接用到爬虫项目中. 下面简单记录一下我用scrapy+r ...
- python绘制立体扇形_认识canvas(画扇形 动态画圆弧(requestAnimationFrame结合settimeout做的动画)、画表盘)...
最近做的两个项目都是关于canvas的,做完整理一下,方便下一次使用,在vue里写的小demo, 功能:画扇形 动态画圆弧(requestAnimationFrame结合settimeout做的动画) ...
- python利用asyncore的端口映射(端口转发)的代码
如下代码是关于python利用asyncore的端口映射(端口转发)的代码. import socket,asyncore class forwarder(asyncore.dispatcher): ...
最新文章
- Linux学习笔记 Day 4~5
- MyBatis 批量更新,批量更新
- 仿码支付全新免签支付系统源码
- docker 环境下通过ocelot和consul 实现服务发现与自治
- jsp嵌入vlc视频回放_【知识】如何用监控进行视频直播?一文了解清楚
- Spring Cloud Hystrix Dashboard仪表盘 和 Turbine集群监控 (学习总结)
- Win10开机免UAC自启动锐捷客户端
- Python日期时间格式转换
- 多线程-生产者消费者模式-CopyOnWriteArrayList索引越界问题
- 项目管理十大知识领域之项目整合管理
- java 打印 xps_使用PrintTicket打印XPS,OutputColor PagesPerSheet无效
- Django的视图函数(二):request对象、视图函数返回值(HTML响应、JsonResponse)、反向解析(视图函数)、HttpResponse子类
- ApacheCN 编程/大数据/数据科学/人工智能学习资源 2019.8
- 流程图 选择结构 (一)
- css td边框重复,表格线边框重复css解决方法
- 揭秘持牌消费金融机构的“潜规则”
- Entering emergency mode. Exit the shell to continue.。。。
- 2017年Android百大框架排行榜
- kudu on impala 基本用法。
- 雨滴特效源码html,js雨滴特效