redis+python 建立免费http-ip代理池;验证+留接口

前言:

效果图:

对于网络上的一些免费代理ip,http的有效性还是不错的;但是,https的可谓是凤毛菱角; 正巧,有一个web可以用http访问,于是我就想到不如直接拿着免费的HTTP代理去做这个!

思路:

1.单页获取ip+port+time (获取time主要是为了后面使用的时候,依照时效可以做文章)

2.整页验证(一个page里面可能有N个ip,通过验证判断有多少个有效ip可以使用)----这里需要使用多线程进行验证;否则,光验证那么多ip都要耗掉不少时间!

import logging
from bs4 import BeautifulSoup
from datetime import datetime, timedelta
import time
import requests
from concurrent.futures import ThreadPoolExecutor# 配置日志记录器
logging.basicConfig(level=logging.ERROR, format='%(asctime)s - %(levelname)s - %(message)s',filename='get_ip_error.log')time_threshold = 15  # 录入IP的时间和当前时间差阈值小于等于15分钟时进行检查
page_valid = 3  # 当每次超过X个有效IP时返回url_kuai= 'http://www.kuaidaili.com/free/inha/'
#请求头
headers = {'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/119.0.0.0 Safari/537.36',
}def check_proxy(p):'''多线程检查代理IP的有效性:param p: 代理IP列表[]:return: 有效的代理IP列表'''url = "http://httpbin.org/ip"  # 用于测试代理IP有效性的网站valid_proxies = []def check_single_proxy(proxy):proxies = {"http": f"http://{proxy['ip']}:{proxy['port']}",# "https": f"https://{proxy['ip']}:{proxy['port']}"}try:response = requests.get(url, proxies=proxies, timeout=1.5)if response.ok:valid_proxies.append(proxy)except requests.exceptions.RequestException as e:pass# 开启多线程检查with ThreadPoolExecutor() as executor:executor.map(check_single_proxy, p)return valid_proxiesdef get_kuaidaili(page):'''获取89ip的代理IP列表:param page: 页码:return: 有效的代理IP列表和页码'''try:valid_ip_list = []while page <= 25:#在这里,只有当有效ip数量>=3的时候,他才会停止;否则,就会不停增加page去爬取;full_url = url_kuai+str(page)   # 根据页码构建URLprint('当前正在爬取网页--->:', full_url)response = requests.get(full_url,headers=headers)if response.ok:html = response.textsoup = BeautifulSoup(html, 'html.parser')table = soup.find('table', class_='table table-b table-bordered table-striped')tbody = table.find('tbody')# if time_diff(tbody,6): #如果时间差在XX分钟以内,就开始检验ip(第6个td是时间) 他更新不快,所以不能用时间去筛选valid_proxies = tbody_add_proxy(tbody,6)  # 获取tbody的数据(time的位置=6)if valid_proxies is not None and len(valid_proxies) > 0:valid_ip_list.extend(valid_proxies)if len(valid_ip_list) >= page_valid:  # 有效 IP 数量大于等于 page_valid 就停止爬取breakpage += 1else:page=0#当page>25的时候,page=1重新开始return valid_ip_list, pageexcept requests.exceptions.RequestException as e:print(f"爬取异常: {e}")return valid_ip_list, pagedef time_diff(table,much):'''查询当前页的IP更新时间,判断是否小于等于阈值 time_threshold,若是返回True:param table: IP表格:return: 时间是否小于等于阈值'''rows = table.find_all('tr')given_time = datetime.strptime(rows[0].find_all('td')[much].text.strip(), "%Y/%m/%d %H:%M:%S")current_time = datetime.now()time_difference = current_time - given_timereturn time_difference <= timedelta(minutes=time_threshold)def tbody_add_proxy(tbody,much):'''提取代理IP和端口信息,并将其构建为列表形式:param tbody: 表格内容:return: 代理IP和端口的列表'''proxy_list = []rows = tbody.find_all('tr')for row in rows:proxy = {}cells = row.find_all('td')proxy["ip"] = cells[0].text.strip()proxy["port"] = cells[1].text.strip()proxy["time"] = cells[much].text.strip()proxy_list.append(proxy)return check_proxy(proxy_list)  #返回有效的ip[(list)]

3.存入redis(我需要考虑的是:ip是否重复了?ip提取的时候什么时候进行补充?)

import redis
import json# 创建连接池
pool_config = {'host': 'localhost','port': 6379,'db': 0,'max_connections': 10,'decode_responses': True,'encoding': 'utf-8'
}# 创建redis连接池
pool = redis.ConnectionPool(**pool_config)def add_to_sorted_set(ip):'''将IP添加到有序集合中,确保唯一性:param ip: IP信息的字典'''r = redis.Redis(connection_pool=pool)ip_de = json.dumps(ip)# 判断IP在有序集合中是否已存在if not r.zscore('valid', ip_de):r.zadd('valid', {ip_de: 0})def find_valid_ip():'''获取当前Redis中有效IP的数量:return: 有效IP的数量'''r = redis.Redis(connection_pool=pool)count = r.zcard('valid') #因为是有序集合,所以需要用zcardif count is None:return 0return countdef pop_from_sorted_set():'''从有序集合中弹出一个元素(按添加顺序):return: 弹出的IP信息字典'''r = redis.Redis(connection_pool=pool)ip_de = r.zrange('valid', 0, 0)[0]# 从有序集合中移除已弹出的元素r.zrem('valid', ip_de)return json.loads(ip_de)

4.如何合理去运行ip的爬取?


from redis_task import redis_task as redis,get_ipimport time
import requests# 配置日志记录器import timedef ip_control():'''1.检查redis里面是否有足够的有效ip(>10)- 足够- 达到目标数量(例如 20)后停止更新- 休眠一段时间后再继续更新- 不足够- 开始从 check_url(url_parse_dict) 获取新的有效ip- 新的ip如果与现有的 redis ip 重复,则不放入- 不重复则放入,直到 redis 有效 ip 数量达到目标数量'''target_count = 20  # 目标有效 IP 数量current_page = 1  # 保存当前页码while True:count = redis.find_valid_ip()print('*******************************************************************')print(f"目前redis里面有{count}个有效ip")if count < target_count:valid_ips, page = get_ip.get_kuaidaili(current_page)  # 使用 current_pageprint(f"当前返回的页码:{page}")if valid_ips:print(f"有效代理IP有:{len(valid_ips)}")redis.add_to_sorted_set(valid_ips)  #必须添加有序集合,确保唯一性 以及后期提取时可以自动移除current_page =page+1  # 更新 current_page,使其递增else:#此时是redis内的有效ip没达到20个print('此时没有达到20个,怎么办?')else:print(f"已经达到目标数量:{target_count},30秒后再更新")time.sleep(10)ip_control()

最后:

当然,此时的`快代理`已经有点不行了.经过我的测试,1~25page 平局只有 8个左右ip有效!  于是需要添加其他的网站------>那么什么是好的免费ip网站呢?  就是一小时内,他的免费ip会更新的,一般都是比较不错的网站!!!    

把这代码搞懂了,需要"素材"的可以私

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/194837.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

STM32串口重定向/实现不定长数据接收

STM32串口重定向/实现不定长数据接收 重定向MicroLIB 不定长数据接收 这是一期STM32内容代码分享&#xff0c;关于STM32重定向的代码和一些出现的问题吗&#xff0c;以及串口接收不定长数据思路 重定向 重定向的功能&#xff1a;能够在STM32中使用printf函数通过串口发送数据 …

Redis:Java客户端

前言 "在当今大数据和高并发的应用场景下&#xff0c;对于数据缓存和高效访问的需求日益增长。而Redis作为一款高性能的内存数据库&#xff0c;以其快速的读写能力和丰富的数据结构成为众多应用的首选。与此同时&#xff0c;Java作为广泛应用于企业级开发的编程语言&…

el-table树形数据隐藏子选择框

0 效果 1 代码 type是table数据中用来区分一级和二级的标识 // 隐藏子合同选择框 cellNone(row) {if (row.row.type 3 || row.row.type 4) {return "checkNone";} }, <style lang"scss" scoped>::v-deep {.checkNone .el-checkbox__input {displa…

INFINI Labs 产品更新 | 发布 Easysearch Java 客户端,Console 支持 SQL 查询等功能

近年来&#xff0c;日志管理平台越来越流行。使用日志管理平台可以实时地、统一地、方便地管理和查看日志&#xff0c;挖掘日志数据价值&#xff0c;驱动运维、运营&#xff0c;提升服务管理效率。 方案架构 Beats 是轻量级采集器&#xff0c;包括 Filebeat、Metricbeat 等。E…

探索计算机视觉技术的应用前景

计算机视觉技术是人工智能领域中一项至关重要的技术&#xff0c;它通过模拟人类视觉系统的工作原理&#xff0c;使计算机能够以一种类似于人类的方式理解和解释图像和视频。这项技术不仅在学术界受到了广泛关注&#xff0c;而且在商业领域也得到了广泛应用。 计算机视觉技术的应…

SpringBoot中日志的使用log4j

SpringBoot中日志的使用log4j 项目中日志系统是必不可少的&#xff0c;目前比较流行的日志框架有 log4j、logback 等&#xff0c;这两个框架的作者是同一个 人&#xff0c;Logback 旨在作为流行的 log4j 项目的后续版本&#xff0c;从而恢复 log4j 离开的位置。 另外 slf4j(…

NI Package Manager创建程序包

NI Package Manager创建程序包 要使用PackageManager创建程序包&#xff0c;即把相关的组件都放在一个目录下&#xff0c;使用命令行创建程序包。 程序包是一个压缩文件&#xff0c;包含要安装到目标位置的所有文件。Package Manager创建的程序包扩展名为.nipkg。可以使用Pack…

【碰碰球】弹珠游戏-微信小程序项目开发流程详解

还记得小时候玩过的弹珠撞击游戏不&#xff0c;这里把它的实现原理通俗易懂地讲一下&#xff0c;看看怎样实现一个碰碰球(弹珠)小游戏&#xff0c;除了个人玩法&#xff0c;也可以双人玩哦&#xff0c;与打乒乓球一样的&#xff0c;可练习临场反应。 创建项目 打开微信开发者…

定点整数、小数

文章目录 一、定点整数二、定点小数三、定点小数的加/减运算 一、定点整数 二、定点小数 三、定点小数的加/减运算 对两个定点小数A、B进行加法/减法时&#xff0c;需要先转换为补码 计算机硬件如何做定点小数补码的加法&#xff1a;从最低位开始&#xff0c;按位相加&#x…

LeetCode【32】最长的有效括号

题目&#xff1a; 思路&#xff1a; 括号字符串依次入栈&#xff0c;删除匹配的成对括号。最后栈中留下的都是无法匹配的断点。这些断点的差值减一就是断点间有效括号串的长度&#xff0c;取这些长度的最大值即可。 例如括号字符串 “)()((())(”&#xff0c;最后留在栈中的…

【C++】入门三

接下来我们说一下引用这个概念&#xff0c;那么什么是引用呢&#xff1f;简单来说引用就是取别名&#xff0c;比如有一个变量叫a&#xff0c;现在我给它取了一个别名叫b&#xff0c;那么此时a和b管理的都是一块空间 这个例子就可以很好的体现a和b管理的是同一块空间&#xff0…

[C/C++] 数据结构 LeetCode:用队列实现栈

题目描述: 请你仅使用两个队列实现一个后入先出&#xff08;LIFO&#xff09;的栈&#xff0c;并支持普通栈的全部四种操作&#xff08;push、top、pop 和 empty&#xff09;。 实现 MyStack 类&#xff1a; void push(int x) 将元素 x 压入栈顶。int pop() 移除并返回栈顶元…