侯体宗的博客
  • 首页
  • Hyperf版
  • beego仿版
  • 人生(杂谈)
  • 技术
  • 关于我
  • 更多分类
    • 文件下载
    • 文字修仙
    • 中国象棋ai
    • 群聊
    • 九宫格抽奖
    • 拼图
    • 消消乐
    • 相册

Python搭建代理IP池实现存储IP的方法

Python  /  管理员 发布于 7年前   180

上一文写了如何从代理服务网站提取 IP,本文就讲解如何存储 IP,毕竟代理池还是要有一定量的 IP 数量才行。存储的方式有很多,直接一点的可以放在一个文本文件中,但操作起来不太灵活,而我选择的是 MySQL 数据库,因为数据库便于管理而且功能强大,当然你还可以选择其他数据库,比如 MongoDB、Redis 等。

代码地址:https://github.com/Stevengz/Proxy_pool

另外三篇:

Python搭建代理IP池(一)- 获取 IP
Python搭建代理IP池(三)- 检测 IP
Python搭建代理IP池(四)- 接口设置与整体调度

使用的库:pymysql

定义规则

数据库存储的主要对象是各个 IP,首先需要保证不重复,另外还需要标 IP 的可用情况,而且需要动态实时处理每个 IP,因此还需要定义一个分数字段,分数是可以重复的,最好是整数类型,每个 IP 都有一个分数,表现其可用性

对于代理池来说,分数可以作为我们判断一个代理可用不可用的标志,我们将设置一个最高分(满分,值由自己设置),代表可用,0 设为最低分,代表不可用。从代理池中获取代理的时候会先从满分 IP 中随机获取一个,注意这里是随机,这样可以保证每个可用 IP 都会被调用到,如果没有满分的就从所有 IP 从随机选一个

分数规则如下:

  • 满分为可用,检测器会定时循环检测每个 IP 的可用情况,一旦检测到有可用的 IP 就立即置为满分,检测到不可用就将分数减 1,减至 0 后移除。
  • 新获取的代理添加时将分数置为 10,当测试可行立即置 100,不可行分数减 1,减至 0 后移除

添加设置

先在一个文件中定义一些配置信息,如数据库的设置、一些不变量如满分的数值等

setting.py

# 数据库地址HOST = '127.0.0.1'# MySql端口MYSQL_PORT = 3306# MySQl用户名、密码MYSQL_USERNAME = '***'MYSQL_PASSWORD = '***'# 数据库名SQL_NAME = 'test'# 代理等级MAX_SCORE = 30MIN_SCORE = 0INITIAL_SCORE = 10# 代理池数量界限POOL_UPPER_THRESHOLD = 1000

MAX_SCORE、MIN_SCORE、INITIAL_SCORE 分别代表最大分数、最小分数、初始分数

定义方法

定义一个类来操作数据库的有序集合,内含一些方法来实现分数的设置、代理的获取等

db.py

import pymysqlfrom error import PoolEmptyErrorfrom setting import *from random import choiceimport reclass MySqlClient(object): # 初始化 def __init__(self, host=HOST, port=MYSQL_PORT, username=MYSQL_USERNAME, password=MYSQL_PASSWORD, sqlname=SQL_NAME):  self.db = pymysql.connect(host=host, user=username, password=password, port=port, db=sqlname)  self.cursor = self.db.cursor() # 添加代理IP def add(self, ip, score=INITIAL_SCORE):  sql_add = "INSERT INTO PROXY (IP,SCORE) VALUES ('%s', %s)" % (ip, score)  if not re.match('\d+\.\d+\.\d+\.\d+\:\d+', ip):   print('代理不符合规范', ip, '丢弃')   return  if not self.exists(ip):   self.cursor.execute(sql_add)   self.db.commit() # 减少代理分数 def decrease(self, ip):  sql_get = "SELECT * FROM PROXY WHERE IP='%s'" % (ip)  self.cursor.execute(sql_get)  score = self.cursor.fetchone()[1]  print(score)  if score and score > MIN_SCORE:   print('代理', ip, '当前分数', score, '减1')   sql_change = "UPDATE PROXY SET SCORE = %s WHERE IP = '%s'" % (score-1, ip)  else:   print('代理', ip, '当前分数', score, '移除')   sql_change = "DELETE FROM PROXY WHERE IP = %s" % (ip)  self.cursor.execute(sql_change)  self.db.commit() # 分数最大化 def max(self, ip):  print('代理', ip, '可用,设置为', MAX_SCORE)  sql_max = "UPDATE PROXY SET SCORE = %s WHERE IP = '%s'" % (MAX_SCORE, ip)  self.cursor.execute(sql_max)  self.db.commit()   # 随机获取有效代理 def random(self):  # 先从满分中随机选一个  sql_max = "SELECT * FROM PROXY WHERE SCORE=%s" % (MAX_SCORE)  if self.cursor.execute(sql_max):   results = self.cursor.fetchall()   return choice(results)[0]  # 没有满分则随机选一个  else:   sql_all = "SELECT * FROM PROXY WHERE SCORE BETWEEN %s AND %s" % (MIN_SCORE, MAX_SCORE)   if self.cursor.execute(sql_all):    results = self.cursor.fetchall()    return choice(results)[0]   else:    raise PoolEmptyError # 判断是否存在 def exists(self, ip):  sql_exists = "SELECT 1 FROM PROXY WHERE IP='%s' limit 1" % ip  return self.cursor.execute(sql_exists)   # 获取数量 def count(self):  sql_count = "SELECT * FROM PROXY"  return self.cursor.execute(sql_count) # 获取全部 def all(self):  self.count()  return self.cursor.fetchall() # 批量获取 def batch(self, start, stop):  sql_batch = "SELECT * FROM PROXY LIMIT %s, %s" % (start, stop - start)  self.cursor.execute(sql_batch)  return self.cursor.fetchall()

方法作用:

  • init():初始化的方法,参数是 MySQL 的连接信息,默认的连接信息已经定义为常量,在 init() 方法中初始化建立 MySQL 连接。这样当 MySqlClient 类初始化的时候就建立了 MySQL 的连接
  • add():向数据库添加代理并设置分数,默认的分数是 INITIAL_SCORE 也就是 10,返回结果是添加的结果
  • decrease():在 检测无效的时候设置分数减 1 的方法,传入代理,然后将此代理的分数减 1,如果达到最低值就删除
  • max():将代理的分数设置为 MAX_SCORE,也就是当 IP 有效时的设置
  • random():随机获取 IP 的方法,首先获取满分的 IP,然后随机选择一个返回,如果不存在满分的 IP,则随机选择一个返回,否则抛出异常
  • exists():判断 IP 是否存在于数据库中
  • count():返回当前 IP个数
  • all():返回所有的 IP,供检测使用
  • batch():返回数据库中从第 start 行开始(从0开始数)的共 stop-start 行数据

抓取保存

当数据库设置好了之后,就可以直接把抓取的 IP 直接放在数据库中了

直接把前面用到的抓取代码更改一下就行了

getter.py

from crawler import Crawlerfrom db import MySqlClientfrom setting import *import sysclass Getter(): def __init__(self):  self.mysql = MySqlClient()  self.crawler = Crawler() # 判断数量是否足够 def is_over_threshold(self):  if self.mysql.count() >= POOL_UPPER_THRESHOLD:   return True  else:   return False  def run(self):  print('获取器开始执行')  if not self.is_over_threshold():   for callback_label in range(self.crawler.__CrawlFuncCount__):    callback = self.crawler.__CrawlFunc__[callback_label]    # 获取代理    all_ip = self.crawler.get_proxies(callback)    sys.stdout.flush()    for ip in all_ip:     self.mysql.add(ip)if __name__ == '__main__': get = Getter() get.run()

结果:

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。


  • 上一条:
    浅析使用Python搭建http服务器
    下一条:
    Python搭建代理IP池实现获取IP的方法
  • 昵称:

    邮箱:

    0条评论 (评论内容有缓存机制,请悉知!)
    最新最热
    • 分类目录
    • 人生(杂谈)
    • 技术
    • linux
    • Java
    • php
    • 框架(架构)
    • 前端
    • ThinkPHP
    • 数据库
    • 微信(小程序)
    • Laravel
    • Redis
    • Docker
    • Go
    • swoole
    • Windows
    • Python
    • 苹果(mac/ios)
    • 相关文章
    • 在python语言中Flask框架的学习及简单功能示例(0个评论)
    • 在Python语言中实现GUI全屏倒计时代码示例(0个评论)
    • Python + zipfile库实现zip文件解压自动化脚本示例(0个评论)
    • python爬虫BeautifulSoup快速抓取网站图片(1个评论)
    • vscode 配置 python3开发环境的方法(0个评论)
    • 近期文章
    • 在go中实现一个常用的先进先出的缓存淘汰算法示例代码(0个评论)
    • 在go+gin中使用"github.com/skip2/go-qrcode"实现url转二维码功能(0个评论)
    • 在go语言中使用api.geonames.org接口实现根据国际邮政编码获取地址信息功能(1个评论)
    • 在go语言中使用github.com/signintech/gopdf实现生成pdf分页文件功能(0个评论)
    • gmail发邮件报错:534 5.7.9 Application-specific password required...解决方案(0个评论)
    • 欧盟关于强迫劳动的规定的官方举报渠道及官方举报网站(0个评论)
    • 在go语言中使用github.com/signintech/gopdf实现生成pdf文件功能(0个评论)
    • Laravel从Accel获得5700万美元A轮融资(0个评论)
    • 在go + gin中gorm实现指定搜索/区间搜索分页列表功能接口实例(0个评论)
    • 在go语言中实现IP/CIDR的ip和netmask互转及IP段形式互转及ip是否存在IP/CIDR(0个评论)
    • 近期评论
    • 122 在

      学历:一种延缓就业设计,生活需求下的权衡之选中评论 工作几年后,报名考研了,到现在还没认真学习备考,迷茫中。作为一名北漂互联网打工人..
    • 123 在

      Clash for Windows作者删库跑路了,github已404中评论 按理说只要你在国内,所有的流量进出都在监控范围内,不管你怎么隐藏也没用,想搞你分..
    • 原梓番博客 在

      在Laravel框架中使用模型Model分表最简单的方法中评论 好久好久都没看友情链接申请了,今天刚看,已经添加。..
    • 博主 在

      佛跳墙vpn软件不会用?上不了网?佛跳墙vpn常见问题以及解决办法中评论 @1111老铁这个不行了,可以看看近期评论的其他文章..
    • 1111 在

      佛跳墙vpn软件不会用?上不了网?佛跳墙vpn常见问题以及解决办法中评论 网站不能打开,博主百忙中能否发个APP下载链接,佛跳墙或极光..
    • 2016-10
    • 2016-11
    • 2018-04
    • 2020-03
    • 2020-04
    • 2020-05
    • 2020-06
    • 2022-01
    • 2023-07
    • 2023-10
    Top

    Copyright·© 2019 侯体宗版权所有· 粤ICP备20027696号 PHP交流群

    侯体宗的博客