forked from jhao104/proxy_pool
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathredisClient.py
155 lines (136 loc) · 4.52 KB
/
redisClient.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
# -*- coding: utf-8 -*-
"""
-----------------------------------------------------
File Name: redisClient.py
Description : 封装Redis相关操作
Author : JHao
date: 2019/8/9
------------------------------------------------------
Change Activity:
2019/08/09: 封装Redis相关操作
2020/06/23: 优化pop方法, 改用hscan命令
2021/05/26: 区别http/https代理
------------------------------------------------------
"""
__author__ = 'JHao'
from redis.exceptions import TimeoutError, ConnectionError, ResponseError
from redis.connection import BlockingConnectionPool
from handler.logHandler import LogHandler
from random import choice
from redis import Redis
import json
class RedisClient(object):
"""
Redis client
Redis中代理存放的结构为hash:
key为ip:port, value为代理属性的字典;
"""
def __init__(self, **kwargs):
"""
init
:param host: host
:param port: port
:param password: password
:param db: db
:return:
"""
self.name = ""
kwargs.pop("username")
self.__conn = Redis(connection_pool=BlockingConnectionPool(decode_responses=True,
timeout=5,
socket_timeout=5,
**kwargs))
def get(self, https):
"""
返回一个代理
:return:
"""
if https:
items = self.__conn.hvals(self.name)
proxies = list(filter(lambda x: json.loads(x).get("https"), items))
return choice(proxies) if proxies else None
else:
proxies = self.__conn.hkeys(self.name)
proxy = choice(proxies) if proxies else None
return self.__conn.hget(self.name, proxy) if proxy else None
def put(self, proxy_obj):
"""
将代理放入hash, 使用changeTable指定hash name
:param proxy_obj: Proxy obj
:return:
"""
data = self.__conn.hset(self.name, proxy_obj.proxy, proxy_obj.to_json)
return data
def pop(self, https):
"""
弹出一个代理
:return: dict {proxy: value}
"""
proxy = self.get(https)
if proxy:
self.__conn.hdel(self.name, json.loads(proxy).get("proxy", ""))
return proxy if proxy else None
def delete(self, proxy_str):
"""
移除指定代理, 使用changeTable指定hash name
:param proxy_str: proxy str
:return:
"""
return self.__conn.hdel(self.name, proxy_str)
def exists(self, proxy_str):
"""
判断指定代理是否存在, 使用changeTable指定hash name
:param proxy_str: proxy str
:return:
"""
return self.__conn.hexists(self.name, proxy_str)
def update(self, proxy_obj):
"""
更新 proxy 属性
:param proxy_obj:
:return:
"""
return self.__conn.hset(self.name, proxy_obj.proxy, proxy_obj.to_json)
def getAll(self, https):
"""
字典形式返回所有代理, 使用changeTable指定hash name
:return:
"""
items = self.__conn.hvals(self.name)
if https:
return list(filter(lambda x: json.loads(x).get("https"), items))
else:
return items
def clear(self):
"""
清空所有代理, 使用changeTable指定hash name
:return:
"""
return self.__conn.delete(self.name)
def getCount(self):
"""
返回代理数量
:return:
"""
proxies = self.getAll(https=False)
return {'total': len(proxies), 'https': len(list(filter(lambda x: json.loads(x).get("https"), proxies)))}
def changeTable(self, name):
"""
切换操作对象
:param name:
:return:
"""
self.name = name
def test(self):
log = LogHandler('redis_client')
try:
self.getCount()
except TimeoutError as e:
log.error('redis connection time out: %s' % str(e), exc_info=True)
return e
except ConnectionError as e:
log.error('redis connection error: %s' % str(e), exc_info=True)
return e
except ResponseError as e:
log.error('redis connection error: %s' % str(e), exc_info=True)
return e