Python搭建代理IP池实现检测IP的方法


Posted in Python onOctober 27, 2019

在获取 IP 时,已经成功将各个网站的代理 IP 获取下来了,然后就需要一个检测模块来对所有的代理进行一轮轮的检测,检测可用就设置为满分,不可用分数就减 1,这样就可以实时改变每个代理的可用情况,在获取有效 IP 的时候只需要获取分数高的 IP

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

另外三篇:
Python搭建代理IP池(一)- 获取 IP
Python搭建代理IP池(二)- 存储 IP
Python搭建代理IP池(四)- 接口设置与整体调度

由于代理 IP 的数量非常多,为了提高 IP 的检测效率,这里使用异步请求库 Aiohttp 来进行检测。至于为什么不用抓取时用的 Requests 库,是因为它是一个同步请求库,在发出一个请求之后需要等待网页加载完成之后才能继续执行程序。这个过程会阻塞在等待响应中,如果服务器响应非常慢,一个请求就会需要十几秒,程序不会继续往下执行

异步请求库就解决了这个问题,在请求发出之后,程序可以继续接下去执行其他的事情,当响应到达时会通知程序再去处理这个响应,这样程序就没有被阻塞,可以充分把时间和资源利用起来

添加设置

增加了几个测试用的常量

setting.py

# 数据库地址
HOST = '127.0.0.1'
# MySql端口
MYSQL_PORT = 3306
# MySQl用户名、密码
MYSQL_USERNAME = '***'
MYSQL_PASSWORD = '***'
# 数据库名
SQL_NAME = 'test'

# 代理等级
MAX_SCORE = 30
MIN_SCORE = 0
INITIAL_SCORE = 10

# 代理池数量界限
POOL_UPPER_THRESHOLD = 1000

VALID_STATUS_CODES = [200, 302]

# 测试API,建议抓哪个网站测哪个
TEST_URL = 'http://www.baidu.com'

# 最大批测试量
BATCH_TEST_SIZE = 30

VALID_STATUS_CODES 变量包含了正常的状态码,获取 Response 后需要判断响应的状态,如果状态码在

VALID_STATUS_CODES 这个列表里,则代表代理可用

定义方法

定义了一个类 Tester,init() 方法中建立了一个 MySqlClient 对象,供类中其他方法使用。接下来定义了一个 test_single_proxy() 方法,用来检测单个代理的可用情况,其参数就是被检测的代理

tester.py

import asyncio
import aiohttp
import time
import sys
from aiohttp import ClientError
from db import MySqlClient
from setting import *


class Tester(object):
 def __init__(self):
  self.mysql = MySqlClient()
 
 # 测试单个代理
 async def test_single_ip(self, ip):
  conn = aiohttp.TCPConnector(verify_ssl=False)
  async with aiohttp.ClientSession(connector=conn) as session:
   try:
    if isinstance(ip, bytes):
     ip = ip.decode('utf-8')
    real_ip = 'http://' + ip
    print('正在测试', ip)
    async with session.get(TEST_URL, proxy=real_ip, timeout=15, allow_redirects=False) as response:
     if response.status in VALID_STATUS_CODES:
      self.mysql.max(ip)
      print('代理可用', ip)
     else:
      self.mysql.decrease(ip)
      print('请求响应码不合法 ', response.status, 'IP', ip)
   except (ClientError, aiohttp.client_exceptions.ClientConnectorError, asyncio.TimeoutError, AttributeError):
    self.mysql.decrease(ip)
    print('代理请求失败', ip)
 
 # 主函数
 def run(self):
  print('测试器开始运行')
  try:
   count = self.mysql.count()
   print('当前剩余', count, '个代理')
   for i in range(0, count, BATCH_TEST_SIZE):
    start = i
    stop = min(i + BATCH_TEST_SIZE, count)
    print('正在测试第', start + 1, '-', stop, '个代理')
    test_ip_group = self.mysql.batch(start, stop)
    loop = asyncio.get_event_loop()
    tasks = [self.test_single_ip(ip_tuple[0]) for ip_tuple in test_ip_group]
    loop.run_until_complete(asyncio.wait(tasks))
    sys.stdout.flush()
    time.sleep(5)
  except Exception as e:
   print('测试器发生错误', e.args)


if __name__ == "__main__":
 test = Tester()
 test.run()

test_single_proxy() 方法前面加了 async 关键词,代表这个方法是异步的,方法内部首先创建了 Aiohttp 的 ClientSession 对象,此对象类似于 Requests 的 Session 对象,可以直接调用该对象的 get() 方法来访问页面

运行结果:

Python搭建代理IP池实现检测IP的方法

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

Python 相关文章推荐
浅谈Python中的闭包
Jul 08 Python
详解如何用OpenCV + Python 实现人脸识别
Oct 20 Python
Python 限制线程的最大数量的方法(Semaphore)
Feb 22 Python
windows下Pycharm安装opencv的多种方法
Mar 05 Python
Windows 下python3.8环境安装教程图文详解
Mar 11 Python
Win 10下Anaconda虚拟环境的教程
May 18 Python
Python中如何引入第三方模块
May 27 Python
Python常见反爬虫机制解决方案
Jun 01 Python
django有哪些好处和优点
Sep 01 Python
如何在Python3中使用telnetlib模块连接网络设备
Sep 21 Python
Python根据字典的值查询出对应的键的方法
Sep 30 Python
python中实现词云图的示例
Dec 19 Python
浅析使用Python搭建http服务器
Oct 27 #Python
Python搭建代理IP池实现存储IP的方法
Oct 27 #Python
Python搭建代理IP池实现获取IP的方法
Oct 27 #Python
详解python statistics模块及函数用法
Oct 27 #Python
在 Jupyter 中重新导入特定的 Python 文件(场景分析)
Oct 27 #Python
python自动结束mysql慢查询会话的实例代码
Oct 27 #Python
python实现输入任意一个大写字母生成金字塔的示例
Oct 27 #Python
You might like
ThinkPHP验证码和分页实例教程
2014/08/22 PHP
php数组中删除元素之重新索引的方法
2014/09/16 PHP
网页的标准,IMG不支持onload标签怎么办
2006/06/29 Javascript
js wmp操作代码小结(音乐连播功能)
2008/11/08 Javascript
js实现广告漂浮效果的小例子
2013/07/02 Javascript
js操纵dom生成下拉列表框的方法
2014/02/24 Javascript
javascript事件函数中获得事件源的两种不错方法
2014/03/17 Javascript
JavaScript中的依赖注入详解
2015/03/18 Javascript
jquery正则表达式验证(手机号、身份证号、中文名称)
2015/12/31 Javascript
webpack中引用jquery的简单实现
2016/06/08 Javascript
深入解析桶排序算法及Node.js上JavaScript的代码实现
2016/07/06 Javascript
js 实现数值的千分位及保存小数方法(推荐)
2016/08/01 Javascript
javascript基本数据类型和转换
2017/03/17 Javascript
微信小程序 蓝牙的实现实例代码
2017/06/27 Javascript
浅析为什么a="abc" 不等于 a=new String("abc")
2017/10/25 Javascript
JS Input里添加小图标的两种方法
2017/11/11 Javascript
基于jquery.page.js实现分页效果
2018/01/01 jQuery
vue.js中实现登录控制的方法示例
2018/04/23 Javascript
详解Ubuntu安装angular-cli遇到的坑
2018/09/08 Javascript
使用Jenkins部署React项目的方法步骤
2019/03/11 Javascript
在vue中高德地图引入和轨迹的绘制的实现
2019/10/11 Javascript
解决echarts 一条柱状图显示两个值,类似进度条的问题
2020/07/20 Javascript
[04:09]显微镜下的DOTA2第十二期—NaVi美如画的团战
2014/06/23 DOTA
python 计算一个字符串中所有数字的和实例
2019/06/11 Python
python tkinter canvas 显示图片的示例
2019/06/13 Python
python编写微信公众号首图思路详解
2019/12/13 Python
Python文件读写w+和r+区别解析
2020/03/26 Python
django配置app中的静态文件步骤
2020/03/27 Python
python高级特性简介
2020/08/13 Python
Saks Fifth Avenue澳洲/亚太地区:萨克斯第五大道精品百货店
2019/06/09 全球购物
乌克兰鞋类购物网站:Eobuv.com.ua
2020/11/28 全球购物
关于期中考试的反思
2014/02/02 职场文书
校园广播稿500字
2014/02/04 职场文书
室内拓展活动方案
2014/02/13 职场文书
研究生毕业自我鉴定范文
2014/03/27 职场文书
承诺书模板
2014/08/30 职场文书