【python】python开源代理ip池

news2025/3/11 3:30:06

一、前言

随着互联网的不断发展,越来越多的应用需要使用高匿代理IP才能访问目标网站,而代理IP作为一种能够隐藏本机真实IP地址的工具,在网络抓取、搜索引擎排名、广告投放、反爬虫等方面有着广泛的应用场景。但是,由于代理IP的稳定性难以保证,而且容易被反爬虫机制识别和封杀,为解决这些问题,我们可以通过构建一个代理IP池来实现代理IP的有效管理和使用。

 本文将介绍如何使用Python语言和开源爬虫框架Scrapy,构建一个高匿代理IP池,并提供完整的代码和案例。

二、代理IP池的构建流程

构建代理IP池的大致流程如下:

  1. 爬取代理IP数据
  2. 验证代理IP的有效性和匿名性
  3. 将有效的代理IP保存到代理IP池中
  4. 从代理IP池中随机获取一个代理IP并使用

接下来,我们将详细介绍每个步骤的实现方式。

2.1、爬取代理IP数据

在构建代理IP池之前,我们需要先收集一些代理IP数据。这里我们可以使用一些代理IP网站上的API接口或者直接爬取网站上的代理IP数据。

以爬取站大爷代理网站为例,其网站上提供了一个可以直接访问的代理IP列表页面,我们可以从该页面中提取出代理IP地址和端口号等信息。

以下为爬取站大爷代理网站的代理IP数据的代码实现:

import scrapy

class XiciSpider(scrapy.Spider):
    name = 'xici'
    allowed_domains = ['www.zdaye.com']
    start_urls = ['https://www.zdaye.com/']

    def parse(self, response):
        item_list = response.xpath('//table[@id="ip_list"]//tr')[1:]
        for item in item_list:
            ip = item.xpath('.//td[2]/text()').get()
            port = item.xpath('.//td[3]/text()').get()
            yield {
                'ip': ip,
                'port': port
            }

以上代码中,我们使用Scrapy框架爬取西刺代理网站,爬取其网页上的代理IP地址和端口号,并以字典的格式保存到内存中。

2.2、验证代理IP的有效性和匿名性

由于代理IP的可用性和匿名性是不稳定的,我们需要定期验证其有效性和匿名性。验证代理IP可用性的方法是通过访问目标网站并获取目标网页的数据,如果获取到了数据,则说明该代理IP可用;否则,则说明该代理IP不可用。

验证代理IP匿名性的方法是通过访问代理IP网站上的检测页面,检测代理IP是否真正地隐藏了客户端的真实IP地址。我们可以使用Python的requests库发起HTTP请求和获取HTTP响应,判断目标网站的状态码和返回的内容是否符合要求。

以下为验证代理IP有效性和匿名性的代码实现:

import requests

def validate_proxy(proxy):
    url = 'http://httpbin.org/get'
    proxies = {
        'http': 'http://{ip}:{port}'.format(**proxy),
        'https': 'https://{ip}:{port}'.format(**proxy)
    }
    try:
        response = requests.get(url, proxies=proxies, timeout=10)
        if response.status_code == 200 and response.json().get('origin'):
            return True
    except:
        pass
    return False

def check_anonymous(proxy):
    url = 'https://www.baidu.com/'
    headers = {
        'User-Agent': 'Mozilla/5.0'
    }
    proxies = {
        'http': 'http://{ip}:{port}'.format(**proxy),
        'https': 'https://{ip}:{port}'.format(**proxy)
    }
    try:
        response = requests.get(url, headers=headers, proxies=proxies, timeout=10)
        if response.status_code == 200 and 'baidu' in response.text:
            return True
    except:
        pass
    return False

以上代码中,我们定义了两个函数validate_proxy和check_anonymous,用于验证代理IP的有效性和匿名性。其中,validate_proxy函数会访问httpbin.org网站,并从响应数据中获取客户端的ip地址,如果获取到了数据,则说明该代理IP可用;否则,则说明不可用。check_anonymous函数会访问百度首页,并判断访问结果是否为正常页面,如果是,则说明代理IP匿名性高;否则,则说明代理IP匿名性低。

2.3、将有效的代理IP保存到代理IP池中

当我们验证出一批有效的代理IP时,可以将其保存到代理IP池中,以便于后续使用。

以下为将代理IP保存到代理IP池中的代码实现:

import redis

class ProxyPool(object):

    def __init__(self):
        self.client = redis.Redis(host='localhost', port=6379, db=0, password='')

    def add(self, proxy):
        self.client.sadd('proxy_pool', str(proxy))

    def remove(self, proxy):
        self.client.srem('proxy_pool', str(proxy))

    def random(self):
        return eval(self.client.srandmember('proxy_pool'))

    def all(self):
        return [eval(p) for p in self.client.smembers('proxy_pool')]

以上代码中,我们使用Redis数据库作为代理IP池的存储工具,通过在Redis中创建一个set类型的key值proxy_pool,来存储所有可用的代理IP。在这里,我们定义了一个名为ProxyPool的类,用于对代理IP池进行增删改查的操作。

2.4、从代理IP池中随机获取一个代理IP并使用

当我们需要使用代理IP访问目标网站时,可以从代理IP池中随机获取一个代理IP,并将其添加到requests库的代理参数proxies中,以便于使用代理IP来访问目标网站。

以下为从代理IP池中随机获取一个代理IP的代码实现:

def get_random_proxy():
    proxy_pool = ProxyPool()
    proxy = proxy_pool.random()
    while not validate_proxy(proxy):
        proxy_pool.remove(proxy)
        proxy = proxy_pool.random()
    return proxy

def download(url):
    proxy = get_random_proxy()
    proxies = {
        'http': 'http://{ip}:{port}'.format(**proxy),
        'https': 'https://{ip}:{port}'.format(**proxy)
    }
    headers = {
        'User-Agent': 'Mozilla/5.0'
    }
    try:
        response = requests.get(url, headers=headers, proxies=proxies, timeout=10)
        if response.status_code == 200:
            return response.text
    except:
        pass
    return None

以上代码中,我们使用get_random_proxy随机获取一个代理IP,并使用validate_proxy函数验证该代理IP是否可用,如果该代理IP不可用,则从代理IP池中删除该代理IP,并重新获取。当获取到可用的代理IP后,我们将其添加到requests库的参数proxies中,并使用requests库来访问目标网站。

三、完整代码实现

将以上代码整合到一个文件中,得到完整的高匿代理IP池的实现方式,代码如下:

import scrapy
import requests
import redis

class XiciSpider(scrapy.Spider):
    name = 'xici'
    allowed_domains = ['www.zdaye.com']
    start_urls = ['http://www.zdaye.com/']

    def parse(self, response):
        item_list = response.xpath('//table[@id="ip_list"]//tr')[1:]
        for item in item_list:
            ip = item.xpath('.//td[2]/text()').get()
            port = item.xpath('.//td[3]/text()').get()
            proxy = {
                'ip': ip,
                'port': port
            }
            if validate_proxy(proxy) and check_anonymous(proxy):
                add_proxy(proxy)

def validate_proxy(proxy):
    url = 'http://httpbin.org/get'
    proxies = {
        'http': 'http://{ip}:{port}'.format(**proxy),
        'https': 'https://{ip}:{port}'.format(**proxy)
    }
    try:
        response = requests.get(url, proxies=proxies, timeout=10)
        if response.status_code == 200 and response.json().get('origin'):
            return True
    except:
        pass
    return False

def check_anonymous(proxy):
    url = 'https://www.baidu.com/'
    headers = {
        'User-Agent': 'Mozilla/5.0'
    }
    proxies = {
        'http': 'http://{ip}:{port}'.format(**proxy),
        'https': 'https://{ip}:{port}'.format(**proxy)
    }
    try:
        response = requests.get(url, headers=headers, proxies=proxies, timeout=10)
        if response.status_code == 200 and 'baidu' in response.text:
            return True
    except:
        pass
    return False

class ProxyPool(object):

    def __init__(self):
        self.client = redis.Redis(host='localhost', port=6379, db=0, password='')

    def add(self, proxy):
        self.client.sadd('proxy_pool', str(proxy))

    def remove(self, proxy):
        self.client.srem('proxy_pool', str(proxy))

    def random(self):
        return eval(self.client.srandmember('proxy_pool'))

    def all(self):
        return [eval(p) for p in self.client.smembers('proxy_pool')]

def add_proxy(proxy):
    proxy_pool = ProxyPool()
    proxy_pool.add(proxy)

def get_random_proxy():
    proxy_pool = ProxyPool()
    proxy = proxy_pool.random()
    while not validate_proxy(proxy):
        proxy_pool.remove(proxy)
        proxy = proxy_pool.random()
    return proxy

def download(url):
    proxy = get_random_proxy()
    proxies = {
        'http': 'http://{ip}:{port}'.format(**proxy),
        'https': 'https://{ip}:{port}'.format(**proxy)
    }
    headers = {
        'User-Agent': 'Mozilla/5.0'
    }
    try:
        response = requests.get(url, headers=headers, proxies=proxies, timeout=10)
        if response.status_code == 200:
            return response.text
    except:
        pass
    return None

if __name__ == '__main__':
    from multiprocessing import Process

    spider_process = Process(target=scrapy.cmdline.execute, args=('scrapy crawl xici',))
    spider_process.start()

    while True:
        url = input('请输入需要访问的URL:')
        print(download(url))

    spider_process.join()

在代码中,我们首先定义了XiciSpider类,用于爬取西刺代理网站上的代理IP数据。然后,我们使用requests库对代理IP进行验证,并使用Redis来保存可用的代理IP。最后,我们定义了get_random_proxy函数,从代理IP池中随机获取一个代理IP,并使用requests库来访问目标网站。

四、总结

Python开源代理IP池是一个非常有用的工具,它可以帮助我们自动爬取和验证代理IP,并将可用的代理IP保存到一个池中,供我们在爬虫或其他需要访问目标网站时使用,可以有效地避免IP被封杀的问题。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

黑客自学路线

谈起黑客,可能各位都会想到:盗号,其实不尽然;黑客是一群喜爱研究技术的群体,在黑客圈中,一般分为三大圈:娱乐圈 技术圈 职业圈。 娱乐圈:主要是初中生和高中生较多,玩网恋…

玩转软件|钉钉个人版内测启动:AI探索未来的工作方式

目录 前言 正文 AI为核心,个人效率为王! 指令中心,解锁AI技巧! 灵感Store,探索更多可能! 未来的AI,即将问世! 个人内测体验 前言 重磅消息:钉钉个人版在8月16日正…

【JavaSE】详解final关键字

在Java中,final可以用来修饰类、方法和变量。final修饰类,表示该类无法被继承,并且此类的设计已被认为很完美而不需要进行修改或扩展。final修饰类中的方法,表示不可以被重写;也就是把该方法锁定了,以防止继…

最小栈00

题目链接 最小栈 题目描述 注意点 pop、top 和 getMin 操作总是在 非空栈 上调用 解答思路 由于栈先进后出的特点,对于任意一次入栈操作,只要该元素未被弹出,则其前面插入的元素一定都还在栈中,所以每次入栈时只需要根据其前…

Lnton羚通视频算法算力云平台【PyTorch】教程:学习Datasets-DataLoader基础知识

Dataset & DataLoader PyTorch 提供了两个数据处理的基本方法:torch.utils.data.DataLoader torch.utils.data.Dataset 允许使用预加载的数据集以及自己的数据。 Dataset 存储样本及其对应的标签, DataLoader 在 Dataset 基础上封装了一个可迭代的对…

苍穹外卖 day3 实现登录过程中MD5加密

一 原来是明文存的 密码可见度太高,MD5加密为密文图像 效果 二 密文实现步骤 修改明文密码,改成密文 123456 密文值:e10adc3949ba59abbe56e057f20f883e代码如下所示 在这里插入代码片 package com.sky.service.impl;import com.sky.con…

[bug日志]springboot多模块启动,在yml配置启动端口8081,但还是启动了8080

【问题描述】 配置的启动端口是8081,实际启动端口是8080 【解决方法】 1.检查application.yml的配置是否有错误(配置项中,显示白色就错,橙色无措) 2.检查pom.xml的打包方式配置项配置,主pom.xml中的配置项一般为:&l…

司徒理财:8.23黄金最新行情走势分析及操作策略

黄金走势分析:      黄金下跌遇阻,短线开启震荡调整走势,但跌势依旧没有改变,没有突破1906压力前,还是偏空走势,反弹继续干空。趋势行情,不要轻言翻转!即便下跌结束,…

DB2的日志

在DB2中,该机制使用日志功能实现。所谓日志,可以被认为在一条事务被落实之前,能够保证其记录被写入永久存储系统的一种方法。 那么为什么需要日志呢?直接把变化的数据写入磁盘不是更好?之所以需要日志,主要…

芯科科技宣布推出下一代暨第三代无线开发平台,打造更智能、更高效的物联网

第三代平台中的人工智能/机器学习引擎可将性能提升100倍以上 Simplicity Studio 6软件开发工具包通过新的开发环境将开发人员带向第三代平台 中国,北京 - 2023年8月22日 – 致力于以安全、智能无线连接技术,建立更互联世界的全球领导厂商Silicon Labs&…

基于IDEA使用maven创建hibernate项目

1、创建maven项目 2、导入hibernate需要的jar包 <!--hibernate核心依赖--><dependency><groupId>org.hibernate</groupId><artifactId>hibernate-core</artifactId><version>5.4.1.Final</version></dependency><!--…

微信小程序:页面有内容却不显示原因

先检查&#xff0c;app.json中这两项路径是否正确 如果正确的话&#xff0c;不显示的那个页面的。js文件中需要Page({})&#xff0c;初始化&#xff0c;这个必须有&#xff1b; 如果还是不出现&#xff0c;可以先把路径删掉&#xff0c;然后刷新一下&#xff0c;这个时候会提示…

ctfshow web入门 web103-web107

1.web103 和102一样 payload: v2115044383959474e6864434171594473&v3php://filter/writeconvert.base64-decode/resource1.php post v1hex2bin2.web104 值只要一样就可以了 payload: v21 post v113.web105 考查的是$$变量覆盖,die可以带出数据,输出一条消息&#xf…

C++信息学奥赛1133:输出亲朋字符串

#include <iostream> #include <string> using namespace std;int main() {string n;cin >> n; // 输入字符串for (int i 0; i < n.length(); i){char Front n[i]; // 当前字符char rear n[i 1]; // 下一个字符if (i n.length() - 1){rear n[0];…

激进的现货白银技巧

在现货白银投资中&#xff0c;我们有保守的交易技巧&#xff0c;也有激进的交易技巧&#xff0c;这给了投资者有进退的选择。其实很多投资者认为贵金属的投资只能长期持有&#xff0c;等待升值&#xff0c;确实有部分投资者是这么做的。但是其实现货白银投资还是有非常激进的一…

这样处理 Python 日志,优雅

迷途小书童的Note 读完需要 4分钟 速读仅需 2 分钟 1 loguru 简介 loguru 是 Python 的一个第三方日志模块&#xff0c;相较于标准库 logging 模块&#xff0c;它提供了更简洁易用的 API&#xff0c;内置丰富的格式化、过滤、文件输出等高级功能。loguru 让 Python 日志记录变得…

HTML5岗位技能实训室建设方案

一 、系统概述 HTML5岗位技能技术是计算机类专业重要的核心课程&#xff0c;课程所包含的教学内容多&#xff0c;实践性强&#xff0c;并且相关技术更新快。传统的课堂讲授模式以教师为中心&#xff0c;学生被动式接收&#xff0c;难以调动学生学习的积极性和主动性。混合式教学…

Maven生命周期、阶段与目标

生命周期 对于Java项目来说&#xff0c;一个项目的生命周期可能会有创建项目、编译、打包、运行、部署等&#xff0c;而maven将项目的生命周期进行了标准化。 Maven默认支持的生命周期有clean、site、default&#xff0c;其中 site这个生命周期几乎用不到&#xff0c;最常用的…

Unity 图片资源的适配

前言 最近小编做Unity项目时&#xff0c;发现在资源处理这方面和Android有所不同&#xff1b;例如&#xff1a;Android的资源文件夹res下会有着mipmap-mdpi&#xff0c;mipmap-hdpi&#xff0c;mipmap-xhdpi&#xff0c;mipmap-xxhdpi&#xff0c;mipmap-xxxhdpi这五个文件夹&a…

java八股文面试[java基础]——Object类有哪些方法

通过IDEA打开Object类就可以看到 &#xff08;1&#xff09;clone方法 保护方法&#xff0c;实现对象的浅复制&#xff0c;只有实现了Cloneable接口才可以调用该方法&#xff0c;否则抛出CloneNotSupportedException异常。 主要是JAVA里除了8种基本类型传参数是值传递&#xf…