Code Monkey home page Code Monkey logo

proxypoolwithui's Introduction

简易好用的免费代理池

兼容系统: Windows Linux MacOS

  • 定时自动爬取网络上的免费代理
  • 定时对代理进行验证,集成API随时返回可用代理
  • 不需要第三方数据库支持,一键启动,简单易用
  • 集成WEB管理界面,方便查看代理状态并对代理池进行配置
  • 拥有详细的注释,可以非常方便地学习或修改

推荐:

项目Demo:http://chenyu0x00.com:8888/

2021年3月8日测试,项目运行半小时后,支持访问HTTPS的代理有40+,支持访问HTTP的代理有100+。

如果你知道有好用的代理源,或者是发现本项目存在一些问题,欢迎通过Issues和我们讨论。

WEB管理界面截图

screenshot1 screenshot2

已经集成的免费代理源

名称 地址 备注
悠悠网络代理 https://uu-proxy.com/
快代理 https://www.kuaidaili.com/
全网代理 http://www.goubanjia.com/
66代理 http://www.66ip.cn/
云代理 http://www.ip3366.net/
免费代理库 https://ip.jiangxianli.com/
小幻HTTP代理 https://ip.ihuan.me/
89免费代理 https://www.89ip.cn/
ProxyScan https://www.proxyscan.io/
开心代理 http://www.kxdaili.com/
西拉代理 http://www.xiladaili.com/
小舒代理 http://www.xsdaili.cn/
ProxyList https://www.proxy-list.download/
ProxyScrape https://proxyscrape.com/ 国内无法直接访问

运行本项目

本项目目前只适配了Python3,请确保你的电脑上安装了3.6或更高版本的Python软件。

  1. 下载代码
git clone https://github.com/OxOOo/ProxyPoolWithUI.git
  1. 安装Python依赖(在ProxyPoolWithUI目录下执行)
pip3 install -i https://pypi.tuna.tsinghua.edu.cn/simple -r requirements.txt
  1. 启动(在ProxyPoolWithUI目录下执行)
python3 main.py

如果你在运行了上述命令之后,在命令行中看到了类似如下截图,那么说明项目成功启动了:

term

  1. 使用浏览器打开http://localhost:5000,可以看到WEB管理界面。

Docker构建项目

  1. 下载项目文件
git clone https://github.com/OxOOo/ProxyPoolWithUI.git
cd ProxyPoolWithUI
  1. 构建docker镜像
docker build --tag proxy_pool .
  1. 运行镜像
docker run -p 5000:5000 -v /root/ProxyPoolWithUI:/proxy -d proxy_pool

/root/ProxyPoolWithUI为clone下来的项目目录路径,请自行更改

使用代理

  1. API接口

项目启动之后,会自动爬取并检测代理是否可用,因此我们只需要关注如何使用代理即可。

  • http://localhost:5000/fetch_random : 随机获取一个可用代理,如果没有可用代理则返回空白

    返回示例 : http://127.0.0.1:8080

  • http://localhost:5000/fetch_all : 获取所有可用代理,如果没有可用代理则返回空白

    返回示例 : http://127.0.0.1:8080,http://127.0.0.1:8081

  1. 使用代理

不同语言使用代理的方式各不相同,这里提供一个Python集成本项目并使用代理的示例代码:

# encoding : utf-8

import requests

def main():
    proxy_uri = requests.get('http://localhost:5000/fetch_random').text
    if len(proxy_uri) == 0:
        print(u'暂时没有可用代理')
        return
    print(u'获取到的代理是:' + proxy_uri)
    
    proxies = { 'http': proxy_uri }
    html = requests.get('http://www.baidu.com', proxies=proxies).text
    if u'百度一下,你就知道' in html:
        print('代理可用')
    else:
        print('代理不可用')

if __name__ == '__main__':
    main()

配置

如果是需要禁用或者启用某些代理,可直接在WEB管理界面进行操作。

本项目的大部分配置均可在config.py中找到,默认配置已经可以适应绝大部分情况,一般来说不需要进行修改。

添加新的代理源

本项目的爬取器均在fetchers目录下,你也可以根据自己的需求对其中的爬取器进行修改或者扩展。

编写本项目的爬取器并不复杂,详细的操作步骤可见此处,可以参考fetchers目录下已有的爬取器。

项目工作流程图

本项目主要包含三部分:

  1. 爬取进程:主要包括fetchers目录和proc/run_fetcher.py文件
  2. 验证进程:主要在proc/run_validator.py文件中
  3. WEB与API:在api目录下

本项目的大致逻辑图如下:

注:为了便于理解与画图,下图的逻辑是经过简化之后的逻辑,详细过程可查看代码以及相应的注释。

workflow

验证算法相关

  1. 如何验证代理可用

目前验证代理可用的算法较为简单,核心**是使用requests库访问一个指定网页,查看是否访问成功。

相关配置参数(包括超时时间尝试次数等)可在config.py中找到,具体代码逻辑在proc/run_validator.py中。

  1. 什么时候该验证哪个代理

这个问题比较复杂,很难有一个完美的解决方案,因此目前的算法较为简单,勉强可用,可在db目录下找到对于目前算法的说明。

如果你有更好的算法,欢迎通过Issues和我们讨论,也可以根据db目录下的README文件对代码进行修改。

proxypoolwithui's People

Contributors

hackeryunen avatar huppygo avatar oxooo avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar

proxypoolwithui's Issues

爬取器应支持在项目部署运行后能够动态新增

我注意到,目前的爬取器都需要在fetchers/init.py下进行相关的实例化操作,若需要新增爬取器,则需要将项目停止部署。对于Docker部署来说,还需要重新build镜像(虽然可以通过volume进行挂载,但是我个人是不推荐这样做的),所以我认为有必要支持在项目能够直接在web端添加爬取器。
我这里提供我的一些想法:

  • 爬取器的相关注册信息应保存在db数据库中
  • 爬取器提供读取数据库再进行相关的实例化操作(可通过eval函数进行Fetcher的动态import,eval属于危险操作,可考虑给web端增加OAuth等,进行相关的权限校验,否则会危害主机自身的安全)

建议conn.py,执行事务操作的时候,加上try/except

很高兴能使用这个开源代码,带有ui,选型了4个,第一个就能跑起来,就打算用起来。
然而因为多线程竞争资源的原因,sqlit3事务事件,数据库锁死,就会出现错误导致程序奔溃退出。
sqlite3我用得也不多。建议如下,既可以同时,也可以选择一个。
1.要么参考https://stackoverflow.com/questions/15856976/transactions-with-python-sqlite3 (答案第1个不过是py2),进行事务处理设置 isolation_level,可能要去掉显式事务语句 https://docs.python.org/3/library/sqlite3.html#sqlite3-controlling-transactions
(py3)
2.要么建议try/except

    c = conn.cursor()
    success = False
    count  = 0
    while not success and count < 5:
        try:
            <sql code>
            success = True
        except:
            <error process code>
            count = count + 1
            time.sleep(3)

自己已经改了下面,不算太官方,毕竟参考其他代码,都是偏设置,所以等待时间,重复次数,我自己偏懒惰,就随意能跑起来就可以了。

proxies 没有对validated 字段加索引

sqlite> .schema
CREATE TABLE proxies
(
fetcher_name VARCHAR(255) NOT NULL,
protocol VARCHAR(32) NOT NULL,
ip VARCHAR(255) NOT NULL,
port INTEGER NOT NULL,
validated BOOLEAN NOT NULL,
latency INTEGER,
validate_date TIMESTAMP,
to_validate_date TIMESTAMP NOT NULL,
validate_failed_cnt INTEGER NOT NULL,
PRIMARY KEY (protocol, ip, port)
);
CREATE INDEX proxies_fetcher_name_index
ON proxies(fetcher_name)
;
CREATE INDEX proxies_to_validate_date_index
ON proxies(to_validate_date ASC)
;
CREATE TABLE fetchers
(
name VARCHAR(255) NOT NULL,
enable BOOLEAN NOT NULL,
sum_proxies_cnt INTEGER NOT NULL,
last_proxies_cnt INTEGER NOT NULL,
last_fetch_date TIMESTAMP,
PRIMARY KEY (name)
);
sqlite>

proxies 没有对validated 字段加索引,但是代码中validated有作为筛选条件,导致查询很慢,fetch_random接口只随机返回一条可用记录就需要2秒多。

def getValidatedRandom(max_count):
"""
从通过了验证的代理中,随机选择max_count个代理返回
max_count<=0表示不做数量限制
返回 : list[Proxy]
"""
if max_count > 0:
r = conn.execute('SELECT * FROM proxies WHERE validated=? ORDER BY RANDOM() LIMIT ?', (True, max_count))
else:
r = conn.execute('SELECT * FROM proxies WHERE validated=? ORDER BY RANDOM()', (True,))
proxies = [Proxy.decode(row) for row in r]
r.close()
return proxies

太卡了

fetch_random等半天,有什么办法优化一下吗?

页面循环提示timeout of 10000ms exceeded

看了下楼下老哥的issues,我的问题和他几乎差不多,都是如果用默认配置在docker运作,也就是说验证线程数量为200,程序执行几个小时之后就会无法提供服务. docker里的最后几行日志为

2022-08-08 00:52:21,635-INFO:validator:完成了32个代理的验证
2022-08-08 00:52:26,748-INFO:validator:完成了19个代理的验证
2022-08-08 00:52:31,882-INFO:validator:完成了20个代理的验证
2022-08-08 00:52:37,067-INFO:validator:完成了27个代理的验证
2022-08-08 00:52:42,223-INFO:validator:完成了23个代理的验证
2022-08-08 00:52:47,361-INFO:validator:完成了22个代理的验证
启动api进程,pid=17267
进程fetcher运行太久,重启
进程validator运行太久,重启
进程api运行太久,重启
启动fetcher进程,pid=6463
启动validator进程,pid=6464
 * Serving Flask app "api.api" (lazy loading)
 * Environment: production
   WARNING: This is a development server. Do not use it in a production deployment.
   Use a production WSGI server instead.
 * Debug mode: off
2022-08-08 00:52:52,648-INFO:fetcher:开始运行一轮爬取器
启动api进程,pid=6465
进程fetcher运行太久,重启
进程validator运行太久,重启
进程api运行太久,重启
启动fetcher进程,pid=6516
启动validator进程,pid=6517
2022-08-08 01:52:52,888-INFO:fetcher:开始运行一轮爬取器
 * Serving Flask app "api.api" (lazy loading)
 * Environment: production
   WARNING: This is a development server. Do not use it in a production deployment.
   Use a production WSGI server instead.
 * Debug mode: off

如果将验证线程数量从200改为50,大概24小时之后会出现服务不可用。暂时原因未知.

有时打不开提示Connection Aborted

大概隔十几秒就会卡三秒,连不上,提示Connection Aborted.服务器应该没有问题,搭别的没有相似情况.是不是什么操作阻塞了进程?

Fetcher被超时卡住系统的情形

run_fetcher.py,

        for item in fetchers:
            data = conn.getFetcher(item.name)
            if data is None:
                logger.error(f'没有在数据库中找到对应的信息:{item.name}')
                raise ValueError('不可恢复错误')
            if not data.enable:
                logger.info(f'跳过爬取器{item.name}')
                continue
            threads.append(threading.Thread(target=run_thread, args=(item.name, item.fetcher, que)))
        [t.start() for t in threads]
        [t.join() for t in threads]

run_thread函数执行过久(即fetcher对应的fetch方法),则后续的写入数据库操作将不再继续进行,操作系统只做存量代理的验证。

代理池验证逻辑可否加快

这边有很多免费代理源,都是GitHub别人分享过来的,基本每分钟更新一次,并区分了协议,自建的代理池每次能获取到3W的代理,但是我自己验证之后仅有几十个存留,请问下验证逻辑有什么要求嘛

可以增加一些友好的配置项

可以增加一些友好的配置项
比如:
为每个spider设置等待时间、因为是爬取站点免费公开信息、更新时间难免不同、统一的等待难免对部分更新快的站点不友好
为spider快捷设置代理、爬取过程中频繁或者根本就是被墙站点就会无法访问、如果能带着库里的代理ip就会友好很多

开心代理挺好用

import logging
import re

import requests
from pyquery import PyQuery as pq

from .BaseFetcher import BaseFetcher

class KxdailiFetcher(BaseFetcher):
"""
http://www.kxdaili.com/dailiip/1/{page}.html
"""

def fetch(self):
    """
    执行一次爬取,返回一个数组,每个元素是(protocol, ip, port),portocol是协议名称,目前主要为http
    返回示例:[('http', '127.0.0.1', 8080), ('http', '127.0.0.1', 1234)]
    """

    ip_regex = re.compile(r'^\d+\.\d+\.\d+\.\d+$')
    port_regex = re.compile(r'^\d+$')
    proxies = []
    urls = []
    urls = urls + [f'http://www.kxdaili.com/dailiip/1/{page}.html' for page in range(1, 11)]
    urls = urls + [f'http://www.kxdaili.com/dailiip/2/{page}.html' for page in range(1, 11)]

    for url in urls:
        html = requests.get(url, timeout=10)
        html.encoding = 'utf-8'
        doc = pq(html.text)
        for line in doc('tr').items():
            tds = list(line('td').items())
            if len(tds) >= 2:
                ip = tds[0].text().strip()
                port = tds[1].text().strip()
                if re.match(ip_regex, ip) is not None and re.match(port_regex, port) is not None:
                    proxies.append(('http', ip, int(port)))

    return list(set(proxies))

能不能兼容一下mysql5.7呢?

能否兼容一下mysql数据库,对有数据库中有效代理增加国家地区字段呢?
增加记录创建时间用于显示存活时间 这个比较简单只需要一个时间字段就可以 类型设置为timestamp 设置不为空 默认值为CURRENT_TIMESTAMP 不根据当前时间时间戳更新
前端能否增加排序功能 如延迟高低排序 国家排序 自定义排序 如国家和延时组合排序

关于run_validator中main函数的效率问题

File: db/conn.py, line 116

time.sleep(0.1) # 为了解决并发读写饿死的问题

不太明白此处sleep的意义。

此函数在proc/run_validator.py 的main函数进行循环调用,但此处的调用仅为单线程调用。
且通过测试发现此处的sleep验证影响了out_que队列的清空,导致整个系统效率的降低。

我尝试将此功能改成独立的进程调用,但是发现sqlite只允许单线程调用,此处的代码存在优化的空间有待解决。

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.