• Stars
    star
    5,329
  • Rank 7,748 (Top 0.2 %)
  • Language
    Python
  • License
    MIT License
  • Created over 7 years ago
  • Updated 8 months ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

An Efficient ProxyPool with Getter, Tester and Server

ProxyPool

build deploy Docker Pulls

简易高效的代理池,提供如下功能:

  • 定时抓取免费代理网站,简易可扩展。
  • 使用 Redis 对代理进行存储并对代理可用性进行排序。
  • 定时测试和筛选,剔除不可用代理,留下可用代理。
  • 提供代理 API,随机取用测试通过的可用代理。

代理池原理解析可见「如何搭建一个高效的代理池」,建议使用之前阅读。

使用准备

首先当然是克隆代码并进入 ProxyPool 文件夹:

git clone https://github.com/Python3WebSpider/ProxyPool.git
cd ProxyPool

然后选用下面 Docker 和常规方式任意一个执行即可。

使用要求

可以通过两种方式来运行代理池,一种方式是使用 Docker(推荐),另一种方式是常规方式运行,要求如下:

Docker

如果使用 Docker,则需要安装如下环境:

  • Docker
  • Docker-Compose

安装方法自行搜索即可。

官方 Docker Hub 镜像:germey/proxypool

常规方式

常规方式要求有 Python 环境、Redis 环境,具体要求如下:

  • Python>=3.6
  • Redis

Docker 运行

如果安装好了 Docker 和 Docker-Compose,只需要一条命令即可运行。

docker-compose up

运行结果类似如下:

redis        | 1:M 19 Feb 2020 17:09:43.940 * DB loaded from disk: 0.000 seconds
redis        | 1:M 19 Feb 2020 17:09:43.940 * Ready to accept connections
proxypool    | 2020-02-19 17:09:44,200 CRIT Supervisor is running as root.  Privileges were not dropped because no user is specified in the config file.  If you intend to run as root, you can set user=root in the config file to avoid this message.
proxypool    | 2020-02-19 17:09:44,203 INFO supervisord started with pid 1
proxypool    | 2020-02-19 17:09:45,209 INFO spawned: 'getter' with pid 10
proxypool    | 2020-02-19 17:09:45,212 INFO spawned: 'server' with pid 11
proxypool    | 2020-02-19 17:09:45,216 INFO spawned: 'tester' with pid 12
proxypool    | 2020-02-19 17:09:46,596 INFO success: getter entered RUNNING state, process has stayed up for > than 1 seconds (startsecs)
proxypool    | 2020-02-19 17:09:46,596 INFO success: server entered RUNNING state, process has stayed up for > than 1 seconds (startsecs)
proxypool    | 2020-02-19 17:09:46,596 INFO success: tester entered RUNNING state, process has stayed up for > than 1 seconds (startsecs)

可以看到 Redis、Getter、Server、Tester 都已经启动成功。

这时候访问 http://localhost:5555/random 即可获取一个随机可用代理。

当然你也可以选择自己 Build,直接运行如下命令即可:

docker-compose -f build.yaml up

如果下载速度特别慢,可以自行修改 Dockerfile,修改:

- RUN pip install -r requirements.txt
+ RUN pip install -r requirements.txt -i https://pypi.douban.com/simple

常规方式运行

如果不使用 Docker 运行,配置好 Python、Redis 环境之后也可运行,步骤如下。

安装和配置 Redis

本地安装 Redis、Docker 启动 Redis、远程 Redis 都是可以的,只要能正常连接使用即可。

首先可以需要一下环境变量,代理池会通过环境变量读取这些值。

设置 Redis 的环境变量有两种方式,一种是分别设置 host、port、password,另一种是设置连接字符串,设置方法分别如下:

设置 host、port、password,如果 password 为空可以设置为空字符串,示例如下:

export PROXYPOOL_REDIS_HOST='localhost'
export PROXYPOOL_REDIS_PORT=6379
export PROXYPOOL_REDIS_PASSWORD=''
export PROXYPOOL_REDIS_DB=0

或者只设置连接字符串:

export PROXYPOOL_REDIS_CONNECTION_STRING='redis://localhost'

这里连接字符串的格式需要符合 redis://[:password@]host[:port][/database] 的格式, 中括号参数可以省略,port 默认是 6379,database 默认是 0,密码默认为空。

以上两种设置任选其一即可。

安装依赖包

这里强烈推荐使用 Condavirtualenv 创建虚拟环境,Python 版本不低于 3.6。

然后 pip 安装依赖即可:

pip3 install -r requirements.txt

运行代理池

两种方式运行代理池,一种是 Tester、Getter、Server 全部运行,另一种是按需分别运行。

一般来说可以选择全部运行,命令如下:

python3 run.py

运行之后会启动 Tester、Getter、Server,这时访问 http://localhost:5555/random 即可获取一个随机可用代理。

或者如果你弄清楚了代理池的架构,可以按需分别运行,命令如下:

python3 run.py --processor getter
python3 run.py --processor tester
python3 run.py --processor server

这里 processor 可以指定运行 Tester、Getter 还是 Server。

使用

成功运行之后可以通过 http://localhost:5555/random 获取一个随机可用代理。

可以用程序对接实现,下面的示例展示了获取代理并爬取网页的过程:

import requests

proxypool_url = 'http://127.0.0.1:5555/random'
target_url = 'http://httpbin.org/get'

def get_random_proxy():
    """
    get random proxy from proxypool
    :return: proxy
    """
    return requests.get(proxypool_url).text.strip()

def crawl(url, proxy):
    """
    use proxy to crawl page
    :param url: page url
    :param proxy: proxy, such as 8.8.8.8:8888
    :return: html
    """
    proxies = {'http': 'http://' + proxy}
    return requests.get(url, proxies=proxies).text


def main():
    """
    main method, entry point
    :return: none
    """
    proxy = get_random_proxy()
    print('get random proxy', proxy)
    html = crawl(target_url, proxy)
    print(html)

if __name__ == '__main__':
    main()

运行结果如下:

get random proxy 116.196.115.209:8080
{
  "args": {},
  "headers": {
    "Accept": "*/*",
    "Accept-Encoding": "gzip, deflate",
    "Host": "httpbin.org",
    "User-Agent": "python-requests/2.22.0",
    "X-Amzn-Trace-Id": "Root=1-5e4d7140-662d9053c0a2e513c7278364"
  },
  "origin": "116.196.115.209",
  "url": "https://httpbin.org/get"
}

可以看到成功获取了代理,并请求 httpbin.org 验证了代理的可用性。

可配置项

代理池可以通过设置环境变量来配置一些参数。

开关

  • ENABLE_TESTER:允许 Tester 启动,默认 true
  • ENABLE_GETTER:允许 Getter 启动,默认 true
  • ENABLE_SERVER:运行 Server 启动,默认 true

环境

  • APP_ENV:运行环境,可以设置 dev、test、prod,即开发、测试、生产环境,默认 dev
  • APP_DEBUG:调试模式,可以设置 true 或 false,默认 true
  • APP_PROD_METHOD: 正式环境启动应用方式,默认是gevent, 可选:tornadomeinheld(分别需要安装 tornado 或 meinheld 模块)

Redis 连接

  • PROXYPOOL_REDIS_HOST / REDIS_HOST:Redis 的 Host,其中 PROXYPOOL_REDIS_HOST 会覆盖 REDIS_HOST 的值。
  • PROXYPOOL_REDIS_PORT / REDIS_PORT:Redis 的端口,其中 PROXYPOOL_REDIS_PORT 会覆盖 REDIS_PORT 的值。
  • PROXYPOOL_REDIS_PASSWORD / REDIS_PASSWORD:Redis 的密码,其中 PROXYPOOL_REDIS_PASSWORD 会覆盖 REDIS_PASSWORD 的值。
  • PROXYPOOL_REDIS_DB / REDIS_DB:Redis 的数据库索引,如 0、1,其中 PROXYPOOL_REDIS_DB 会覆盖 REDIS_DB 的值。
  • PROXYPOOL_REDIS_CONNECTION_STRING / REDIS_CONNECTION_STRING:Redis 连接字符串,其中 PROXYPOOL_REDIS_CONNECTION_STRING 会覆盖 REDIS_CONNECTION_STRING 的值。
  • PROXYPOOL_REDIS_KEY / REDIS_KEY:Redis 储存代理使用字典的名称,其中 PROXYPOOL_REDIS_KEY 会覆盖 REDIS_KEY 的值。

处理器

  • CYCLE_TESTER:Tester 运行周期,即间隔多久运行一次测试,默认 20 秒
  • CYCLE_GETTER:Getter 运行周期,即间隔多久运行一次代理获取,默认 100 秒
  • TEST_URL:测试 URL,默认百度
  • TEST_TIMEOUT:测试超时时间,默认 10 秒
  • TEST_BATCH:批量测试数量,默认 20 个代理
  • TEST_VALID_STATUS:测试有效的状态码
  • API_HOST:代理 Server 运行 Host,默认 0.0.0.0
  • API_PORT:代理 Server 运行端口,默认 5555
  • API_THREADED:代理 Server 是否使用多线程,默认 true

日志

  • LOG_DIR:日志相对路径
  • LOG_RUNTIME_FILE:运行日志文件名称
  • LOG_ERROR_FILE:错误日志文件名称
  • LOG_ROTATION: 日志记录周转周期或大小,默认 500MB,见 loguru - rotation
  • LOG_RETENTION: 日志保留日期,默认 7 天,见 loguru - retention
  • ENABLE_LOG_FILE:是否输出 log 文件,默认 true,如果设置为 false,那么 ENABLE_LOG_RUNTIME_FILE 和 ENABLE_LOG_ERROR_FILE 都不会生效
  • ENABLE_LOG_RUNTIME_FILE:是否输出 runtime log 文件,默认 true
  • ENABLE_LOG_ERROR_FILE:是否输出 error log 文件,默认 true

以上内容均可使用环境变量配置,即在运行前设置对应环境变量值即可,如更改测试地址和 Redis 键名:

export TEST_URL=http://weibo.cn
export REDIS_KEY=proxies:weibo

即可构建一个专属于微博的代理池,有效的代理都是可以爬取微博的。

如果使用 Docker-Compose 启动代理池,则需要在 docker-compose.yml 文件里面指定环境变量,如:

version: "3"
services:
  redis:
    image: redis:alpine
    container_name: redis
    command: redis-server
    ports:
      - "6379:6379"
    restart: always
  proxypool:
    build: .
    image: "germey/proxypool"
    container_name: proxypool
    ports:
      - "5555:5555"
    restart: always
    environment:
      REDIS_HOST: redis
      TEST_URL: http://weibo.cn
      REDIS_KEY: proxies:weibo

扩展代理爬虫

代理的爬虫均放置在 proxypool/crawlers 文件夹下,目前对接了有限几个代理的爬虫。

若扩展一个爬虫,只需要在 crawlers 文件夹下新建一个 Python 文件声明一个 Class 即可。

写法规范如下:

from pyquery import PyQuery as pq
from proxypool.schemas.proxy import Proxy
from proxypool.crawlers.base import BaseCrawler

BASE_URL = 'http://www.664ip.cn/{page}.html'
MAX_PAGE = 5

class Daili66Crawler(BaseCrawler):
    """
    daili66 crawler, http://www.66ip.cn/1.html
    """
    urls = [BASE_URL.format(page=page) for page in range(1, MAX_PAGE + 1)]

    def parse(self, html):
        """
        parse html file to get proxies
        :return:
        """
        doc = pq(html)
        trs = doc('.containerbox table tr:gt(0)').items()
        for tr in trs:
            host = tr.find('td:nth-child(1)').text()
            port = int(tr.find('td:nth-child(2)').text())
            yield Proxy(host=host, port=port)

在这里只需要定义一个 Crawler 继承 BaseCrawler 即可,然后定义好 urls 变量和 parse 方法即可。

  • urls 变量即为爬取的代理网站网址列表,可以用程序定义也可写成固定内容。
  • parse 方法接收一个参数即 html,代理网址的 html,在 parse 方法里只需要写好 html 的解析,解析出 host 和 port,并构建 Proxy 对象 yield 返回即可。

网页的爬取不需要实现,BaseCrawler 已经有了默认实现,如需更改爬取方式,重写 crawl 方法即可。

欢迎大家多多发 Pull Request 贡献 Crawler,使其代理源更丰富强大起来。

部署

本项目提供了 Kubernetes 部署脚本,如需部署到 Kubernetes,请参考 kubernetes

待开发

  • 前端页面管理
  • 使用情况统计分析

如有一起开发的兴趣可以在 Issue 留言,非常感谢!

LICENSE

MIT

More Repositories

1

Python3WebSpider

Source File of My Book related to WebSpider
1,994
star
2

DouYin

API of DouYin for Humans used to Crawl Popular Videos and Musics
Python
642
star
3

CookiesPool

Cookies Pool
Python
540
star
4

AdslProxy

Adsl Proxy Pool
Python
234
star
5

TaobaoProduct

Taobao Product Spider by Selenium
Python
191
star
6

ScrapyRedisBloomFilter

Scrapy Redis Bloom Filter
Python
173
star
7

DeepLearningSlideCaptcha2

Deep LearningImage Captcha 2
Python
161
star
8

CrackGeetest

Crack Geetest
Python
155
star
9

Weibo

Weibo Spider Using Scrapy
Python
136
star
10

MaoYan

MaoYan TOP 100 Movie
Python
128
star
11

Jiepai

Jiepai Pictures of Toutiao
Python
123
star
12

Weixin

Sougou Weixin Spider Using Proxy
Python
86
star
13

RecaptchaResolver

Recaptcha Resolver
Python
84
star
14

ScrapySeleniumTest

Scrapy Selenium on Taobao Product
Python
84
star
15

DeepLearningSlideCaptcha

Deep Learning Slide Captcha
Python
74
star
16

WeiboList

WeiboList of MaYun
Python
65
star
17

GithubLogin

Login Github with Requests
Python
64
star
18

Moments

Wechat Friends Circle Spider
Python
56
star
19

CrackWeiboSlide

Crack Weibo Slide Captcha
Python
55
star
20

ScrapyUniversal

Scrapy Universal Spider
Python
54
star
21

ScrapyTutorial

Scrapy Tutorial
Julia
49
star
22

ProxyTunnel

Proxy Tunnel using Squid LoadBalancer
Shell
48
star
23

ProxySettings

Proxy Settings
Python
43
star
24

Images360

Download Images From 360 Using Scrapy
Python
42
star
25

PyppeteerTest

Pyppeteer Demo
Python
41
star
26

HCaptchaResolver

HCaptcha Resolver
Python
38
star
27

ScrapeStatic1

Spider for https://static1.scrape.cuiqingcai.com/
Python
34
star
28

AccountPool

Account Pool
Python
33
star
29

WeiboCrawler

Weibo Crawler for All Sites
Python
32
star
30

MitmAppiumJD

MitmProxy and Appium to Crawl Comments in JD APP
Python
31
star
31

ScrapySplashTest

Scrapy Splash on Taobao Product
Python
30
star
32

AjaxHookSpider

Ajax Hook Demo
JavaScript
29
star
33

PlaywrightTest

Playwright Test
Python
28
star
34

CrackTouClick

Crack Touch Click
Python
27
star
35

CrackImageCaptcha

Crack Image Code by Tesserocr
Python
24
star
36

ScrapeSsr1

Scrape Ssr1
Python
24
star
37

ScrapyPyppeteerDeprecated

Scrapy Pyppeteer Demo
HTML
23
star
38

ElasticSearchTest

Elastic Search Code
Python
22
star
39

DeepLearningImageCaptcha

DeepLearning Image Captcha
Python
22
star
40

CrackSlideCaptcha

Crack Slide Captcha
Python
16
star
41

ScrapyCrawlSpider

Scrapy Crawl Spider
Python
16
star
42

JavaScriptObfuscate

Demo of JavaScript Obfuscate
JavaScript
16
star
43

ProxyTest

Proxy Demo
Python
15
star
44

UrllibTest

Urllib Demo
Python
11
star
45

ScrapyPyppeteer

Scrapy Pyppeteer Demo
Python
11
star
46

CodeServer

Code Server
Dockerfile
11
star
47

Scrape

Platform of Web Views to Scrape
Python
10
star
48

SeleniumTest

Selenium Demo
Python
10
star
49

ScrapeSpa5

Spider for https://spa5.scrape.center/
Python
9
star
50

IGetGet

IGetGet Books Spider by MitmDump
Python
9
star
51

ScrapydDocker

Docker for Scrapyd
Dockerfile
8
star
52

BookCrawler

Book Crawler
Python
8
star
53

Installation

Instructions for Installation of Software or Packages
8
star
54

AsyncTest

Async HTTP Demo
Python
8
star
55

Deobfuscate

Deobfuscate Samples
JavaScript
7
star
56

RequestsTest

Requests Test
Python
6
star
57

ScrapyDocker

Docker for Scrapy Demo
Python
6
star
58

Universal

Universal Scrapy
Python
6
star
59

ScrapeDynamic1

Spider for Dynamic1
Python
6
star
60

CaptchaPlatform

Captcha Platform Demo
Python
6
star
61

MovieCrawler

Movie Crawler
Python
6
star
62

ScrapeCaptcha3

Spider for https://captcha3.scrape.cuiqingcai.com/
Python
5
star
63

ScrapyCompositeDemo

Scrapy Composite Demo
Python
5
star
64

MySQLTest

MySQL Test Demo
Python
5
star
65

TestTess

Test Tesseract and Tesserocr
Python
5
star
66

Qunar

Qunar Spider
Python
5
star
67

ScrapyDownloaderTest

Test Downloader Middleware of Scrapy
Python
5
star
68

FileStorageTest

File Storage Test
Python
4
star
69

ScrapeSpa2

Spider for https://spa2.scrape.center
Python
4
star
70

XposedTest

Xposed Demo
Java
4
star
71

ScrapyCrawlSpiderTest

Scrapy Universal Spider
Python
4
star
72

ScrapeAntispider5

Scrape Antispier5
Python
4
star
73

WebDriverDetection

Detect WebDriver and Pretend Browser
JavaScript
4
star
74

BeautifulSoupTest

Beautiful Soup Test
Python
4
star
75

ScrapeLogin2

Spider for https://login2.scrape.cuiqingcai.com/
Python
3
star
76

ScrapySpiderMiddlewareDemo

Scrapy Spider Middleware Demo
Python
3
star
77

MultiprocessingTest

Demo of Multiprocessing
Python
3
star
78

ScrapeLogin3

Spider for https://login3.scrape.cuiqingcai.com/
Python
3
star
79

PyQueryTest

PyQuery Demo
Python
3
star
80

XPathTest

XPath Test
Python
3
star
81

UnidbgServer

Unidbg Server
Java
3
star
82

RegexTest

Regex Demo
Python
3
star
83

AppiumTest

Appium Test
Python
3
star
84

ScrapeSpa1

Scrape Spa1
Python
3
star
85

MitmProxyTest

Mitm Proxy Test
Python
2
star
86

PlaywrightIntercepting

Playwright Intercepting
JavaScript
2
star
87

NewsCrawler

News Crawler
Python
2
star
88

BrowserMobProxyTest

Browser Mob Proxy Test
Python
2
star
89

ScrapeSpa6

Spider for https://spa6.scrape.center
Python
2
star
90

ScrapeAntispider3

Scrape Antispider3
Python
2
star
91

RabbitMQTest

RabbitMQ Test
Python
2
star
92

LearnAST

AST Demo
JavaScript
2
star
93

ParselTest

Parsel Test Demo
Python
2
star
94

ScrapySeleniumDemo

Scrapy Selenium Demo
Python
2
star
95

ScrapydDeploy

Scrapyd Deploy Template for Azure
2
star
96

ScrapeSpa14

Scrape Spa14
Python
1
star
97

ScrapeSpa7

Scrape Spa7
JavaScript
1
star
98

HttpxTest

Scrape Spa16
Python
1
star
99

ScrapeApp9

Scrape App9
Python
1
star
100

ScrapeAntispider6

Scrape Antispider6
Python
1
star