基于付费代理的代理IP池
项目来源
此项目为微软某个工程师构建的代理IP池,我对此进行了改造。可以用于生产环境中的爬虫项目
阅读前建议
阅读我之前发布的爬虫基础的文章,了解代理如何获取、使用等。
分为四大模块
- 代理生成
- 基于购买的付费代理接口获取代理IP,利用redis数据库的有序集合进行存储。初始序为10。
- 检测模块检测时,若检测成功,将序变为100,若检测失败,将序减一,直至减为0则抛弃此代理
- 代理检测利用redis数据库的zsan方法每次从数据库中取出20条数据和游标,每20条20条地进行检测。
- 首先检测代理IP的格式(检测是否含有冒号,若有则根据冒号进行分割获取IP和Port,分别检测IP(根据 '.' 进行分割,判断是否包含4部分且每部分是证书且在0到255之间则为有效)和Port(判断是否是整数)
- 之后检测代理IP是否可用,找一个检测IP网站。不加代理访问并记作IP1,加代理访问记作IP2,判断IP1和IP2是否不相等,再判断加的代理IP和IP2是否相等,来决定此代理是否有效
- 再用此代理IP去访问通用的网站(百度)或者你要爬取的网站,如果状态码在200到302之间,那么认为代理IP检测通过,将序改为100,若检测失败,则将序减一
- 检测模块采取了协程机制,增加检测速度
- 代理存储
- 封装了redis数据库的一些操作供其他三个模块调用
- 接口模块
- 将代理IP从redis数据库中读出,通过Flask开接口的方式展示到前台。
- 展示代理规则:优先随机展示序为100的,没有100的再随机展示序为10到100的
本地部署
前提:电脑已经装好了redis和redis可视化工具(如果不会装,可以私信我)
-
conda 建立一个虚拟环境
conda create -n new_env python=3.x # 替换 x 为你需要的 Python 版本
-
激活新建环境
conda activate new_env
-
安装依赖项
pip install -r requirments.txt
-
更改项目 settings.py 配置项
python# redis host REDIS_HOST = env.str('REDIS_HOST', '127.0.0.1') # redis port REDIS_PORT = env.int('REDIS_PORT', 6379) # redis password, if no password, set it to None REDIS_PASSWORD = env.str('REDIS_PASSWORD', None) # redis db, if no choice, set it to 0 REDIS_DB = env.int('REDIS_DB', 0) # redis connection string, like redis://[password]@host:port or rediss://[password]@host:port/0 # redis hash table key name REDIS_KEY = env.str('REDIS_KEY', 'proxies:universal') # 前面是标识符,后面是redis数据库的表名 # definition of proxy scores PROXY_SCORE_MAX = 100 # 如果检测成功,序设置为100 PROXY_SCORE_MIN = 0 # 接口模块取代理时会优先取序为100的,没有的话再取PROXY_SCORE_MIN和PROXY_SCORE_MAX之间的代理,这里可以自行设置 PROXY_SCORE_INIT = 10 # 代理IP初始序 # definition of proxy number # PROXY_NUMBER_MAX = 50000 PROXY_NUMBER_MAX = 5 # 代理IP池容量 PROXY_NUMBER_MIN = 0 # definition of tester # 检测代理IP是否有效的测试网址,但是需要改成http:避免ssl验证 TEST_URL = env.str('TEST_URL', 'http://www.baidu.com') # TEST_URL = env.str('TEST_URL', 'https://antispider7.scrape.center/login') TEST_TIMEOUT = env.int('TEST_TIMEOUT', 10) TEST_BATCH = env.int('TEST_BATCH', 20) # 检测成功的状态码 TEST_VALID_STATUS = env.list('TEST_VALID_STATUS', [200, 206, 302]) # definition of api # 端口模块相关配置 API_HOST = env.str('API_HOST', '127.0.0.1') API_PORT = env.int('API_PORT', 5555) API_THREADED = env.bool('API_THREADED', True) # flags of enable # 是否开启对应模块 ENABLE_TESTER = env.bool('ENABLE_TESTER', True) ENABLE_GETTER = env.bool('ENABLE_GETTER', True) ENABLE_SERVER = env.bool('ENABLE_SERVER', True)
-
修改代理IP提取链接urls(proxypool/crawlers/base.py)
python@logger.catch def crawl(self): """ crawl main method """ # for url in self.urls: # logger.info(f'fetching {url}') # html = self.fetch(url) # time.sleep(.5) # for proxy in self.parse(html):#在父类里调用自身方法,此处的proxy是一页链接的代理IP列表 # logger.info(f'fetched proxy {proxy.string()} from {url}') # yield proxy#此处的proxy是返回的是所有页的代理IP列表 # 小象代理提取代理IP的链接 urls = "https://api.xiaoxiangdaili.com/ip/get?appKey=1130083050647343104&appSecret=5ch2dc4Q&cnt=5&wt=json&method=https&city=&province=" logger.info(f'fetching {urls}') html = self.fetch(urls) time.sleep(.5) for proxy in self.parse(html): # 在父类里调用自身方法,此处的proxy是一页链接的代理IP列表 logger.info(f'fetched proxy {proxy.string()} from {urls}') yield proxy # 此处的proxy是返回的是所有页的代理IP列表
-
运行redis服务
-
运行run.py文件
-
通过访问http://127.0.0.1:5555即可访问代理IP池的前台
- /all:全部代理IP
- /random:根据规则(上面模块讲解过)展示随机一个代理IP
- /count:代理IP数量
项目源码
有意私信我也可以(微信公众号)