python构建IP代理池(Proxy Pool)

2023-10-29

基本原理

代理实际上指的就是代理服务器,它的功能是代理网络用户去取得网络信息 。也可以说它是网络信息的中转站 。

在我们正常请求一个网站时, 是将请求发送给 Web 服务器,Web 服务器把响应传回给我们 。 如果设置了代理服务器 , 实际上就是在本机和服务器之间搭建了一个桥, 此时本机不是直接 向 Web 服务器发起请求,而是向代理服务器发出请求,请求会发送给代理服务器,然后由代理服务器再发送给 Web 服务器,接着由代理服务器再把 Web 服务器返回的响应转发给本机。 这样我们同样可以正常访问网页,但这个过程中 Web 服务器识别出的真实 IP 就不再是我们本机的 IP 了,就成功实现了 IP 伪装,解决爬虫中封IP的难题。

了解代理服务器的基本原理后,我们不禁会想到几个问题,代理IP从何而来?如何保证代理可用性?代理如何存储?如何使用这些代理?

  • 获取代理IP: 爬取网站的免费代理。比如西刺、快代理之类有免费代理的网站, 但是这些免费代理大多数情况下都是不好用的,所以比较靠谱的方法是购买付费代理。当然,如果你有更好的代理接口也可以自己接入。
  • 检测IP代理可用性: 因为免费代理大部分是不可用的,所以采集回来的代理IP不能直接使用,可以写检测程序不断的去用这些代理访问一个稳定的网站,看是否可以正常使用。
  • 存储代理IP: 存储的代理IP首先要保证代理不重复 , 要检测代理的可用情况,还要动态实时处理每个代理,本文利用来MongoDB存储,当然也可用其他方式存储。
  • 使用代理:最简单的办法就是用 API 来提供对外服务的接口 。

 

IP代理池设计

我们了解了代理池的四大问题,所以我们可以根据这四个问题去分析设计一个代理池框架,我们可以分成四个模块。分别是获取模块、检测模块、存储模块、接口模块 。这样不仅有利于我们的维护,也使得可以更高效的完成我们的需求。

  • 架构图

代码模块

在这里只是简单的写出了代码模块的实现,并不完整不具有逻辑性,如想查看获取源代码,请移步到GitHub:https://github.com/wanhaiwei/proxypool

 

  • 获取模块
import requests
import chardet
import traceback
from lxml import etree

class Downloader(object):
    def __init__(self):
        self.headers = {
            'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.3440.106 Safari/537.36'
        }

    def download(self, url):
        print('正在下载页面:{}'.format(url))
        try:
            resp = requests.get(url, headers=self.headers)
            resp.encoding = chardet.detect(resp.content)['encoding']

            if resp.status_code == 200:
                return self.xpath_parse(resp.text)

            else:
                raise ConnectionError
        except Exception:
            print('下载页面出错:{}'.format(url))
            traceback.print_exc()

    def xpath_parse(self, resp):
        try:
            page = etree.HTML(resp)
            trs = page.xpath('//div[@id="list"]/table/tbody/tr')
            proxy_list = []
            for tr in trs:
                ip = tr.xpath('./td[1]/text()')[0]
                port = tr.xpath('./td[2]/text()')[0]
                proxy = {
                    'proxy': ip + ':' + port
                }
                proxy_list.append(proxy)
            return proxy_list
        except Exception:
            print('解析IP地址出错')
            traceback.print_exc()

if __name__ == '__main__':
    print(Downloader().download('https://www.kuaidaili.com/free/inha/1/'))
  • 存储模块
import pymongo
from pymongo.errors import DuplicateKeyError


class MongoDB(object):
    def __init__(self):
        self.client = pymongo.MongoClient()
        self.db = self.client['proxypool3']
        self.proxies = self.db['proxies']
        self.proxies.ensure_index('proxy', unique=True)
        self.proxies.create_index()
                    #  createIndex()
    def insert(self, proxy):
        try:
            self.proxies.insert(proxy)
            print('插入成功:{}'.format(proxy))
        except DuplicateKeyError:
            pass

    def delete(self, conditions):
        self.proxies.remove(conditions)
        print('删除成功:{}'.format(conditions))

    def update(self, conditions, values):
        self.proxies.update(conditions, {"$set": values})
        print('更新成功:{},{}'.format(conditions,values))

    def get(self, count, conditions=None):
        conditions = conditions if conditions else {}
        count = int(count)
        items = self.proxies.find(conditions, limit=count).sort('delay', pymongo.ASCENDING)
        items = list(items)
        return items

    def get_count(self):
        return self.proxies.count({})


if __name__ == '__main__':
    m = MongoDB()
    print(m.get(3))
  • 检测模块
import requests
import time
import traceback
from requests.exceptions import ProxyError, ConnectionError
from db.mongo_db import MongoDB
from multiprocessing.pool import ThreadPool


def valid_many(proxy_list, method):
    pool = ThreadPool(16)

    for proxy in proxy_list:
        pool.apply_async(valid_one, args=(proxy, method))
    pool.close()
    pool.join()


def valid_one(proxy, method, url='https://www.baidu.com'):
    headers = {
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.3440.106 Safari/537.36'
    }
    proxies = {
        'http': 'http://' + proxy['proxy'],
        'https': 'http://' + proxy['proxy']
    }

    try:
        start_time = time.time()
        # requests.packages.urllib3.disable_warnings()
        resp = requests.get(url, headers=headers, proxies=proxies, timeout=5, verify=False)
        delay = round(time.time() - start_time, 2)

        if resp.status_code == 200:
            proxy['delay'] = delay
            if method == 'insert':

                MongoDB().insert(proxy)
            elif method == 'check':
                MongoDB().update({'proxy': proxy['proxy']}, {'delay': proxy['delay']})
        else:
            if method == 'check':
                MongoDB().delete({'proxy': proxy['proxy']})
    except (ProxyError, ConnectionError):
        if method == 'check':
            MongoDB().delete({'proxy': proxy['proxy']})
    except Exception:
        traceback.print_exc()
  • API接口模块
import flask
import json
from db.mongo_db import MongoDB


app = flask.Flask(__name__)


@app.route('/one')
def get_one():
    proxies = MongoDB().get(1)
    result = [proxy['proxy'] for proxy in proxies]
    return json.dumps(result)


@app.route('/many')
def get_many():
    args = flask.request.args
    proxies = MongoDB().get(args['count'])
    result = [proxy['proxy'] for proxy in proxies]
    return json.dumps(result)

def run():
    app.run()
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

python构建IP代理池(Proxy Pool) 的相关文章

随机推荐

  • vue,elementui更改文件名下载,并添加el-progress进度条

    功能 vue elementui更改文件名下载 下载添加el progress进度条 需求 公司需要下载fastdfs文件系统文件 通过http方式 并修改下载的文件名 ps 跨域问题通过配置nginx解决 下载组件代码如下
  • 基于BC-linux/Centos下的K8S单机环境搭建

    搭建前环境准备 配置虚拟机 详细的配置流程比较简单 这里就直接放配置完成的设置 处理器是4个单核 内存是8G 硬盘空间是60G 重点是网络适配器选择NAT模式 另外这里的镜像是选择的BC linux 基于Centos下的 版本是7 6的 下
  • TCP拥塞控制

    拥塞 在某段时间 若对网络中某资源的需求超过了该资源所能提供的可用部分 网络的性能就要变坏 产生拥塞 congestion 拥塞原因 某结点缓存容量太小 某链路带宽不足 某些处理机处理效率太慢 拥塞会累积 不断加剧 增加资源并不能从根本上解
  • QtXlsx编译、使用笔记

    换个方式操作ms office excel 第一次知道QtXlsx 记录一下使用方式 项目地址 http qtxlsx debao me 网上说的编译方式没搞定 vs2013 qt5 5 1加入pro文件 pri文件 都失败 用了一个简单方
  • IIS安装配置和简单网站部署流程

    IIS安装和网站配置 环境 win10 注意 这是在win10下部署iis 开发环境下部署 开发测试 非windows server IIS简介 Internet Information Services 简称IIS 是微软提供基于wind
  • 零基础小白如何入门python爬虫?3年程序员分享python爬虫学习攻略(文内有福利)

    如果你是非计算机专业 完全是零基础编程 这篇文章就是专门为你写的 内容不长 2分钟就能看完 但还是希望能给你一些帮助 以前从纯白零基础学Python 很多坑都没人踩 现在经常看到很多Python学习群里的新朋友总是喊着 从入门到放弃 觉得学
  • 【ROS】ROS1人机界面开发:在QtCreator中创建ROS1功能包

    ROS 郭老二博文之 ROS目录 1 版本要求 ROS的QtCreator插件要和QtCreator版本对应一致 否则报错 本人QtCreator版本为 10 0 1 需要下载安装ros qtc plugin的版本也要为10 0版本 2 安
  • 用Python绘制地理图

    当您的数据包含地理信息时 丰富的地图可视化可以为您理解数据和解释分析结果的最终用户提供重要价值 Plotly Plotly是一个著名的库 用于在Python中创建交互式绘图和仪表板 安装Plotly 在命令提示符中运行这两个命令 以在我们的
  • 六、windows环境下netcat的安装及使用

    windows环境下netcat的安装及使用 s小菜鸟 2019 01 03 21 05 51 5080 收藏 14 1 下载netcat 下载地址 https eternallybored org misc netcat 2 解压文件 3
  • Java中的NIO编程

    1 BIO和NIO简介 BIO NIO AIO简介 1 Java BIO 同步并阻塞 传统阻塞型 服务器实现模式为一个连接一个线程 即客户端有连接请求时服务器端就需要启动一个线程进行处理 如果这个连接不做任何事情会造成不必要的线程开销 2
  • 中国天气网全城市代码weather_cityId

    Ctrl F 查询 城市名字 http mobile weather com cn data forecast 101010100 html 1381891660081 北京 gt 101010100 海淀 gt 101010200 朝阳
  • 【openWrt】自定义后台访问端口

    通过ssh访问openwrt系统 修改 ect config uhttpd文件 再重启openwrt即可
  • 无人不苦,不必喊疼

    张爱玲说 生活是一袭华美的长袍 里面爬满了虱子 对于大多数人来说 生活都是外面光鲜亮丽 里面却各有各的苦楚 尤其对于成人 更是早已被生活的风霜 侵袭得体无完肤 可是 生活再不易 也总要拼尽了全力往前走 才能趟过荆棘丛生 走上康庄大道 1成人
  • ArrayList源码分析(基于JDK11)

    ArrayList源码分析 基于JDK11 类字段 private static final long serialVersionUID 8683452581122892189L private static final int DEFAU
  • JMETER:Uncaught exception in thread Thread

    Uncaught exception in thread Thread AWT EventQueue 0 6 main 调用测试片段错误 循环调用了
  • Jmeter中正则表达式提取器使用详解

    转载地址 http blog csdn net quiet girl article details 50724313 在使用Jmeter过程中 会经常使用到正则表达式提取器提取器 虽然并不直接涉及到请求的测试 但是对于数据的传递起着很大的
  • linux查看磁盘io性能

    1 查看磁盘 IO 性能 1 1 top 命令 top 命令通过查看 CPU 的 wa 值来判断当前磁盘 IO 性能 如果这个数值过大 很可能是磁盘 IO 太高了 当然也可能是其他原因 例如网络 IO 过高等 1 2 sar 命令 sar
  • Jupyter Notebook使用-如何设置代码单元启用自动换行

    最近开始使用 Jupyter Notebook 至于它的强大功能不需要我做过多介绍 接下来直接进入正题 在使用的过程中我发现了一个这样的问题 当编辑的代码过长时将会出现滚动条 滑动条 像下面这样 但是当我将滚动条拉到底时 问题出现了 侧边栏
  • 代码审计-Java项目&JDBC&Mybatis&Hibernate&注入&预编译&写法

    文章目录 Javaweb 数据库操作 模式 写法 预编译等 环境搭建 JDBC 注入分析 关于预编译 Mybatis 注入分析 Hibernate 注入分析 总结 Javaweb 代码审计SQL注入 INXEDU在线网校 Javaweb 数
  • python构建IP代理池(Proxy Pool)

    基本原理 代理实际上指的就是代理服务器 它的功能是代理网络用户去取得网络信息 也可以说它是网络信息的中转站 在我们正常请求一个网站时 是将请求发送给 Web 服务器 Web 服务器把响应传回给我们 如果设置了代理服务器 实际上就是在本机和服