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中非常实用的一些功能和函数分享
Feb 14 Python
Python中用于转换字母为小写的lower()方法使用简介
May 19 Python
Linux上安装Python的PIL和Pillow库处理图片的实例教程
Jun 23 Python
Python实现查询某个目录下修改时间最新的文件示例
Aug 29 Python
pycharm运行出现ImportError:No module named的解决方法
Oct 13 Python
Windows 安装 Anaconda3+PyCharm的方法步骤
Jun 13 Python
python爬取王者荣耀全皮肤的简单实现代码
Jan 31 Python
Python中os模块功能与用法详解
Feb 26 Python
在Matplotlib图中插入LaTex公式实例
Apr 17 Python
浅析python 定时拆分备份 nginx 日志的方法
Apr 27 Python
python如何求圆的面积
Jul 01 Python
Python循环之while无限迭代
Apr 30 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
一步一步学习PHP(7) php 字符串相关应用
2010/03/05 PHP
php 7新特性之类型申明详解
2017/06/06 PHP
分享5个非常有用的Laravel Blade指令
2018/05/30 PHP
PHP使用HTML5 FormData对象提交表单操作示例
2019/07/02 PHP
php日志函数error_log用法实例分析
2019/09/23 PHP
jQuery fadeTo方法调整图片的透明度使用介绍
2013/05/06 Javascript
Jquery实现图片左右自动滚动示例
2013/09/25 Javascript
JavaScript中的object转换成number或string规则介绍
2014/12/31 Javascript
jQuery源码解读之removeClass()方法分析
2015/02/20 Javascript
使用JavaScript刷新网页的方法
2015/06/04 Javascript
JavaScript中利用Array和Object实现Map的方法
2015/07/27 Javascript
深入浅析Nodejs的Http模块
2017/06/20 NodeJs
vue mint-ui 实现省市区街道4级联动示例(仿淘宝京东收货地址4级联动)
2017/10/16 Javascript
React Native自定义控件底部抽屉菜单的示例
2018/02/08 Javascript
Express本地测试HTTPS的示例代码
2018/06/06 Javascript
AngularJs的UI组件ui-Bootstrap之Tooltip和Popover
2018/07/13 Javascript
vue.js表单验证插件(vee-validate)的使用教程详解
2019/05/23 Javascript
javascript实现随机抽奖功能
2020/12/30 Javascript
[01:44]剑指西雅图 展望TI之CIS战队专访
2014/06/25 DOTA
Python中用Descriptor实现类级属性(Property)详解
2014/09/18 Python
利用 Monkey 命令操作屏幕快速滑动
2016/12/07 Python
Python 安装setuptools和pip工具操作方法(必看)
2017/05/22 Python
Tensorflow之构建自己的图片数据集TFrecords的方法
2018/02/07 Python
Django中url的反向查询的方法
2018/03/14 Python
Python iter()函数用法实例分析
2018/03/17 Python
Python使用jsonpath-rw模块处理Json对象操作示例
2018/07/31 Python
解决新django中的path不能使用正则表达式的问题
2018/12/18 Python
python实现智能语音天气预报
2019/12/02 Python
Python MySQL 日期时间格式化作为参数的操作
2020/03/02 Python
利用python实现平稳时间序列的建模方式
2020/06/03 Python
Python如何在bool函数中取值
2020/09/21 Python
html5的新玩法——语音搜索
2013/01/03 HTML / CSS
英国虚拟主机服务商:eUKhost
2016/08/16 全球购物
学生党员的自我评价范文
2014/03/01 职场文书
英文请假条
2014/04/11 职场文书
VS2019连接MySQL数据库的过程及常见问题总结
2021/11/27 MySQL