Skip to content

Commit eb2d5d5

Browse files
committed
优化及添加cookie池文档
1 parent 1cee596 commit eb2d5d5

4 files changed

Lines changed: 82 additions & 30 deletions

File tree

docs/source_code/CookiePool.md

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
# Cookie池使用说明
2+
3+
cookie池分为三种,使用场景如下
4+
1. `PageCookiePool`:从不需要登录的页面获取cookie
5+
2. `LoginCookiePool`:有大量账号,自动切换登录,获取登录后cookie
6+
3. `LimitTimesUserPool`:账号昂贵,需要限制使用次数、使用频率、使用时间段、账号独占使用
7+
8+
## PageCookiePool
9+
10+
### 快速尝鲜
11+
```
12+
from feapder.network.cookie_pool import PageCookiePool
13+
14+
cookie_pool = PageCookiePool(redis_key="test:page_cookie_pool", page_url="https://www.baidu.com")
15+
cookies = cookie_pool.get_cookie()
16+
print(cookies)
17+
```
18+
19+
执行上面代码,会自动获取百度的cookie,存放到redis里,然后返回获取到的cookie
20+
21+
### 使用进阶
22+
23+
PageCookiePool参数
24+
25+
- redis_key:
26+
- page_url: 生产cookie的url
27+
- min_cookies: 最小cookie数
28+
- must_contained_keys: cookie 必须包含的key
29+
- keep_alive: 当cookie数量足够是是否保持随时待命,生产cookie的状态。False为否,满足则退出
30+
- **kwargs:WebDriver的一些参数,具体可参考源码注释
31+
32+
33+
34+
## LoginCookiePool
35+
## LimitTimesUserPool

feapder/network/cookie_pool.py

Lines changed: 26 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -410,16 +410,14 @@ class LimitTimesUserStatus(Enum):
410410
class LimitTimesUser:
411411
"""
412412
有次数限制的账户
413-
基于本地做的缓存,不支持多进程调用
414413
"""
415414

416-
ACCOUNT_INFO_KEY = "accounts:h_account_info" # 存储cookie的redis key
417-
SITE_NAME = "" # 网站名
418-
419415
redisdb = None
420416

421417
def __init__(
422418
self,
419+
redis_key,
420+
*,
423421
username,
424422
password,
425423
max_search_times,
@@ -428,13 +426,15 @@ def __init__(
428426
**kwargs,
429427
):
430428
"""
429+
@param redis_key: cookie存储位置
431430
@param username:
432431
@param password:
433432
@param max_search_times:
434433
@param proxies:
435434
@param search_interval: 调用时间间隔。 支持元组 指定间隔的时间范围 如(5,10)即5到10秒;或直接传整数
436435
"""
437436
self.__dict__.update(kwargs)
437+
self.redis_key = "{}:h_cookie_pool".format(redis_key)
438438
self.username = username
439439
self.password = password
440440
self.max_search_times = max_search_times
@@ -487,7 +487,7 @@ def __eq__(self, other):
487487
return self.username == other.username
488488

489489
def sync_account_info_from_redis(self):
490-
account_info = self.redisdb.hget(self.ACCOUNT_INFO_KEY, self.username)
490+
account_info = self.redisdb.hget(self.redis_key, self.username)
491491
if account_info:
492492
account_info = eval(account_info)
493493
self.account_info.update(account_info)
@@ -499,15 +499,11 @@ def cookies(self):
499499

500500
def set_cookies(self, cookies):
501501
self.account_info["cookies"] = cookies
502-
return self.redisdb.hset(
503-
self.ACCOUNT_INFO_KEY, self.username, self.account_info
504-
)
502+
return self.redisdb.hset(self.redis_key, self.username, self.account_info)
505503

506504
def set_login_time(self, login_time=None):
507505
self.account_info["login_time"] = login_time or time.time()
508-
return self.redisdb.hset(
509-
self.ACCOUNT_INFO_KEY, self.username, self.account_info
510-
)
506+
return self.redisdb.hset(self.redis_key, self.username, self.account_info)
511507

512508
def get_login_time(self):
513509
return self.account_info.get("login_time")
@@ -549,9 +545,7 @@ def update_status(self):
549545
self.account_info["search_times"] += 1
550546
self.account_info["last_search_time"] = time.time()
551547

552-
return self.redisdb.hset(
553-
self.ACCOUNT_INFO_KEY, self.username, self.account_info
554-
)
548+
return self.redisdb.hset(self.redis_key, self.username, self.account_info)
555549

556550
@property
557551
def search_times(self):
@@ -563,7 +557,7 @@ def search_times(self):
563557
self.account_info["search_times"] = 0
564558
self.account_info["init_search_times_time"] = current_time
565559

566-
self.redisdb.hset(self.ACCOUNT_INFO_KEY, self.username, self.account_info)
560+
self.redisdb.hset(self.redis_key, self.username, self.account_info)
567561

568562
return self.account_info["search_times"]
569563

@@ -583,9 +577,7 @@ def is_at_work_time(self):
583577

584578
def del_cookie(self):
585579
self.account_info["cookies"] = {}
586-
return self.redisdb.hset(
587-
self.ACCOUNT_INFO_KEY, self.username, self.account_info
588-
)
580+
return self.redisdb.hset(self.redis_key, self.username, self.account_info)
589581

590582
def create_cookie(self):
591583
"""
@@ -624,9 +616,9 @@ def login(self):
624616
except Exception as e:
625617
log.exception(e)
626618
send_msg(
627-
msg=f"{self.SITE_NAME} {self.username} 账号登陆异常 exception: {str(e)}",
619+
msg=f"{self.redis_key} {self.username} 账号登陆异常 exception: {str(e)}",
628620
level="error",
629-
message_prefix=f"{self.SITE_NAME} {self.username} 账号登陆异常",
621+
message_prefix=f"{self.redis_key} {self.username} 账号登陆异常",
630622
)
631623

632624
log.info("登录失败 {}".format(self.username))
@@ -636,14 +628,21 @@ def login(self):
636628

637629
class LimitTimesUserPool:
638630
"""
639-
限制查询次数的用户的User pool
640-
基于本地做的缓存,不支持多进程调用
631+
限制查询次数的用户的UserPool
641632
"""
642633

643634
LOAD_USER_INTERVAL = 60
644635

645-
def __init__(self, *, accounts_dict, limit_user_class, support_more_client=True):
636+
def __init__(
637+
self,
638+
redis_key,
639+
*,
640+
accounts_dict: dict,
641+
limit_user_class: LimitTimesUser.__class__,
642+
support_more_client: bool = True,
643+
):
646644
"""
645+
@param redis_key: cookie存储位置
647646
@param accounts_dic: 账户信息字典
648647
{
649648
"15011300228": {
@@ -657,6 +656,7 @@ def __init__(self, *, accounts_dict, limit_user_class, support_more_client=True)
657656
@param limit_user_class: 用户重写的 limit_user_class
658657
@param support_more_client: 是否支持多客户端 即多线程 多进程模式 (可能在计数上及使用频率上有些误差)
659658
"""
659+
self.redis_key = redis_key
660660
self.accounts_dict = accounts_dict
661661
self.limit_user_class = limit_user_class
662662

@@ -675,7 +675,9 @@ def __load_users(self, username=None):
675675
if username and username != _username:
676676
continue
677677

678-
limit_times_users = self.limit_user_class(username=_username, **detail)
678+
limit_times_users = self.limit_user_class(
679+
self.redis_key, username=_username, **detail
680+
)
679681
if limit_times_users in self.limit_times_users:
680682
continue
681683

feapder/utils/webdriver.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -193,10 +193,10 @@ def chrome_driver(self):
193193

194194
if self._executable_path:
195195
driver = webdriver.Chrome(
196-
chrome_options=chrome_options, executable_path=self._executable_path
196+
options=chrome_options, executable_path=self._executable_path
197197
)
198198
else:
199-
driver = webdriver.Chrome(chrome_options=chrome_options)
199+
driver = webdriver.Chrome(options=chrome_options)
200200

201201
# 隐藏浏览器特征
202202
with open(os.path.join(os.path.dirname(__file__), "./js/stealth.min.js")) as f:

tests/test_cookie_pool.py

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,23 @@
88
@email: boris_liu@foxmail.com
99
"""
1010

11-
from feapder.network.cookie_pool import LoginCookiePool
11+
from feapder.network.cookie_pool import PageCookiePool,LoginCookiePool, LimitTimesUserPool
1212

13-
cookie_pool = LoginCookiePool("test:login_cookie_pool", tab_userbase="test_userbase")
14-
cookie = cookie_pool.get_cookie()
15-
print(cookie)
13+
14+
import unittest
15+
16+
17+
18+
class TestCookiePool(unittest.TestCase):
19+
def test_page_cookie_pool(self):
20+
cookie_pool = PageCookiePool(redis_key="test:page_cookie_pool", page_url="https://www.baidu.com")
21+
cookies = cookie_pool.get_cookie()
22+
print(cookies)
23+
24+
def test_login_cookie_pool(self):
25+
cookie_pool = LoginCookiePool("test:login_cookie_pool", tab_userbase="test_userbase")
26+
cookie = cookie_pool.get_cookie()
27+
print(cookie)
28+
29+
if __name__ == "__main__":
30+
unittest.main()

0 commit comments

Comments
 (0)