├── .gitignore
├── README.md
├── cookiespool
├── __init__.py
├── api.py
├── config.py
├── db.py
├── generator.py
├── importer.py
├── scheduler.py
└── tester.py
├── importer.py
├── login
├── __init__.py
└── weibo
│ ├── __init__.py
│ ├── cookies.py
│ └── templates
│ ├── 1234.png
│ ├── 1243.png
│ ├── 1324.png
│ ├── 1342.png
│ ├── 1423.png
│ ├── 1432.png
│ ├── 2134.png
│ ├── 2143.png
│ ├── 2314.png
│ ├── 2341.png
│ ├── 2413.png
│ ├── 2431.png
│ ├── 3124.png
│ ├── 3142.png
│ ├── 3214.png
│ ├── 3241.png
│ ├── 3412.png
│ ├── 3421.png
│ ├── 4123.png
│ ├── 4132.png
│ ├── 4213.png
│ ├── 4231.png
│ ├── 4312.png
│ └── 4321.png
├── requirements.txt
└── run.py
/.gitignore:
--------------------------------------------------------------------------------
1 | /.idea
2 | *.pyc
3 | ghostdriver.log
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # CookiesPool
2 |
3 | 可扩展的Cookies池,目前对接了新浪微博,[m.weibo.cn](https://m.weibo.cn),可自行扩展其他站点
4 |
5 |
6 | ## 安装
7 |
8 | ```
9 | pip3 install -r requirements.txt
10 | ```
11 |
12 | ## 基础配置
13 |
14 | ### 接口基本配置
15 |
16 | ```python
17 | # Redis数据库地址
18 | REDIS_HOST = 'localhost'
19 |
20 | # Redis端口
21 | REDIS_PORT = 6379
22 |
23 | # Redis密码,如无填None
24 | REDIS_PASSWORD = 'foobared'
25 |
26 | # 产生器使用的浏览器
27 | BROWSER_TYPE = 'Chrome'
28 |
29 | # 产生器类,如扩展其他站点,请在此配置
30 | GENERATOR_MAP = {
31 | 'weibo': 'WeiboCookiesGenerator'
32 | }
33 |
34 | # 测试类,如扩展其他站点,请在此配置
35 | TESTER_MAP = {
36 | 'weibo': 'WeiboValidTester'
37 | }
38 |
39 | # 检测器检测接口
40 | TEST_URL_MAP = {
41 | 'weibo': 'https://m.weibo.cn/api/container/getIndex?uid=1804544030&type=uid&page=1&containerid=1076031804544030'
42 | }
43 |
44 | # 产生器和验证器循环周期
45 | CYCLE = 120
46 |
47 | # API地址和端口
48 | API_HOST = '0.0.0.0'
49 | API_PORT = 5000
50 |
51 | ```
52 |
53 | ### 进程开关
54 |
55 | 在config.py修改
56 |
57 | ```python
58 | # 产生器开关,模拟登录添加Cookies
59 | GENERATOR_PROCESS = True
60 | # 验证器开关,循环检测数据库中Cookies是否可用,不可用删除
61 | VALID_PROCESS = True
62 | # API接口服务
63 | API_PROCESS = True
64 | ```
65 |
66 |
67 | ## 账号购买
68 |
69 | 账号可在淘宝购买
70 |
71 |
72 | ## 导入账号
73 |
74 | ```
75 | python3 importer.py
76 | ```
77 |
78 | ```
79 | 请输入账号密码组, 输入exit退出读入
80 | 18459748505----astvar3647
81 | 14760253606----gmidy8470
82 | 14760253607----uoyuic8427
83 | 18459749258----rktfye8937
84 | 账号 18459748505 密码 astvar3647
85 | 录入成功
86 | 账号 14760253606 密码 gmidy8470
87 | 录入成功
88 | 账号 14760253607 密码 uoyuic8427
89 | 录入成功
90 | 账号 18459749258 密码 rktfye8937
91 | 录入成功
92 | exit
93 | ```
94 |
95 |
96 | ## 运行
97 |
98 | 请先导入一部分账号之后再运行,运行命令:
99 |
100 | ```
101 | python3 run.py
102 | ```
103 |
104 | ## 运行效果
105 |
106 | 三个进程全部开启:
107 |
108 |
109 | ```
110 | API接口开始运行
111 | * Running on http://0.0.0.0:5000/ (Press CTRL+C to quit)
112 | Cookies生成进程开始运行
113 | Cookies检测进程开始运行
114 | 正在生成Cookies 账号 14747223314 密码 asdf1129
115 | 正在测试Cookies 用户名 14747219309
116 | Cookies有效 14747219309
117 | 正在测试Cookies 用户名 14740626332
118 | Cookies有效 14740626332
119 | 正在测试Cookies 用户名 14740691419
120 | Cookies有效 14740691419
121 | 正在测试Cookies 用户名 14740618009
122 | Cookies有效 14740618009
123 | 正在测试Cookies 用户名 14747222472
124 | Cookies有效 14747222472
125 | Cookies检测完成
126 | 验证码位置 420 580 384 544
127 | 成功匹配
128 | 拖动顺序 [1, 4, 2, 3]
129 | 成功获取到Cookies {'SUHB': '08J77UIj4w5n_T', 'SCF': 'AimcUCUVvHjswSBmTswKh0g4kNj4K7_U9k57YzxbqFt4SFBhXq3Lx4YSNO9VuBV841BMHFIaH4ipnfqZnK7W6Qs.', 'SSOLoginState': '1501439488', '_T_WM': '99b7d656220aeb9207b5db97743adc02', 'M_WEIBOCN_PARAMS': 'uicode%3D20000174', 'SUB': '_2A250elZQDeRhGeBM6VAR8ifEzTuIHXVXhXoYrDV6PUJbkdBeLXTxkW17ZoYhhJ92N_RGCjmHpfv9TB8OJQ..'}
130 | 成功保存Cookies
131 | ```
132 |
--------------------------------------------------------------------------------
/cookiespool/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Python3WebSpider/CookiesPool/e724f8d19b17970e79f1a8b942ae943b6fcf12c2/cookiespool/__init__.py
--------------------------------------------------------------------------------
/cookiespool/api.py:
--------------------------------------------------------------------------------
1 | import json
2 | from flask import Flask, g
3 | from cookiespool.config import *
4 | from cookiespool.db import *
5 |
6 | __all__ = ['app']
7 |
8 | app = Flask(__name__)
9 |
10 | @app.route('/')
11 | def index():
12 | return '
Welcome to Cookie Pool System
'
13 |
14 |
15 | def get_conn():
16 | """
17 | 获取
18 | :return:
19 | """
20 | for website in GENERATOR_MAP:
21 | print(website)
22 | if not hasattr(g, website):
23 | setattr(g, website + '_cookies', eval('RedisClient' + '("cookies", "' + website + '")'))
24 | setattr(g, website + '_accounts', eval('RedisClient' + '("accounts", "' + website + '")'))
25 | return g
26 |
27 |
28 | @app.route('//random')
29 | def random(website):
30 | """
31 | 获取随机的Cookie, 访问地址如 /weibo/random
32 | :return: 随机Cookie
33 | """
34 | g = get_conn()
35 | cookies = getattr(g, website + '_cookies').random()
36 | return cookies
37 |
38 |
39 | @app.route('//add//')
40 | def add(website, username, password):
41 | """
42 | 添加用户, 访问地址如 /weibo/add/user/password
43 | :param website: 站点
44 | :param username: 用户名
45 | :param password: 密码
46 | :return:
47 | """
48 | g = get_conn()
49 | print(username, password)
50 | getattr(g, website + '_accounts').set(username, password)
51 | return json.dumps({'status': '1'})
52 |
53 |
54 | @app.route('//count')
55 | def count(website):
56 | """
57 | 获取Cookies总数
58 | """
59 | g = get_conn()
60 | count = getattr(g, website + '_cookies').count()
61 | return json.dumps({'status': '1', 'count': count})
62 |
63 |
64 | if __name__ == '__main__':
65 | app.run(host='0.0.0.0')
66 |
--------------------------------------------------------------------------------
/cookiespool/config.py:
--------------------------------------------------------------------------------
1 | # Redis数据库地址
2 | REDIS_HOST = 'localhost'
3 |
4 | # Redis端口
5 | REDIS_PORT = 6379
6 |
7 | # Redis密码,如无填None
8 | REDIS_PASSWORD = 'foobared'
9 |
10 | # 产生器使用的浏览器
11 | BROWSER_TYPE = 'Chrome'
12 |
13 | # 产生器类,如扩展其他站点,请在此配置
14 | GENERATOR_MAP = {
15 | 'weibo': 'WeiboCookiesGenerator'
16 | }
17 |
18 | # 测试类,如扩展其他站点,请在此配置
19 | TESTER_MAP = {
20 | 'weibo': 'WeiboValidTester'
21 | }
22 |
23 | TEST_URL_MAP = {
24 | 'weibo': 'https://m.weibo.cn/'
25 | }
26 |
27 | # 产生器和验证器循环周期
28 | CYCLE = 120
29 |
30 | # API地址和端口
31 | API_HOST = '0.0.0.0'
32 | API_PORT = 5000
33 |
34 | # 产生器开关,模拟登录添加Cookies
35 | GENERATOR_PROCESS = False
36 | # 验证器开关,循环检测数据库中Cookies是否可用,不可用删除
37 | VALID_PROCESS = False
38 | # API接口服务
39 | API_PROCESS = True
40 |
--------------------------------------------------------------------------------
/cookiespool/db.py:
--------------------------------------------------------------------------------
1 | import random
2 | import redis
3 | from cookiespool.config import *
4 |
5 |
6 | class RedisClient(object):
7 | def __init__(self, type, website, host=REDIS_HOST, port=REDIS_PORT, password=REDIS_PASSWORD):
8 | """
9 | 初始化Redis连接
10 | :param host: 地址
11 | :param port: 端口
12 | :param password: 密码
13 | """
14 | self.db = redis.StrictRedis(host=host, port=port, password=password, decode_responses=True)
15 | self.type = type
16 | self.website = website
17 |
18 | def name(self):
19 | """
20 | 获取Hash的名称
21 | :return: Hash名称
22 | """
23 | return "{type}:{website}".format(type=self.type, website=self.website)
24 |
25 | def set(self, username, value):
26 | """
27 | 设置键值对
28 | :param username: 用户名
29 | :param value: 密码或Cookies
30 | :return:
31 | """
32 | return self.db.hset(self.name(), username, value)
33 |
34 | def get(self, username):
35 | """
36 | 根据键名获取键值
37 | :param username: 用户名
38 | :return:
39 | """
40 | return self.db.hget(self.name(), username)
41 |
42 | def delete(self, username):
43 | """
44 | 根据键名删除键值对
45 | :param username: 用户名
46 | :return: 删除结果
47 | """
48 | return self.db.hdel(self.name(), username)
49 |
50 | def count(self):
51 | """
52 | 获取数目
53 | :return: 数目
54 | """
55 | return self.db.hlen(self.name())
56 |
57 | def random(self):
58 | """
59 | 随机得到键值,用于随机Cookies获取
60 | :return: 随机Cookies
61 | """
62 | return random.choice(self.db.hvals(self.name()))
63 |
64 | def usernames(self):
65 | """
66 | 获取所有账户信息
67 | :return: 所有用户名
68 | """
69 | return self.db.hkeys(self.name())
70 |
71 | def all(self):
72 | """
73 | 获取所有键值对
74 | :return: 用户名和密码或Cookies的映射表
75 | """
76 | return self.db.hgetall(self.name())
77 |
78 |
79 | if __name__ == '__main__':
80 | conn = RedisClient('accounts', 'weibo')
81 | result = conn.set('hell2o', 'sss3s')
82 | print(result)
83 |
--------------------------------------------------------------------------------
/cookiespool/generator.py:
--------------------------------------------------------------------------------
1 | import json
2 | from selenium import webdriver
3 | from selenium.webdriver import DesiredCapabilities
4 | from cookiespool.config import *
5 | from cookiespool.db import RedisClient
6 | from login.weibo.cookies import WeiboCookies
7 |
8 |
9 | class CookiesGenerator(object):
10 | def __init__(self, website='default'):
11 | """
12 | 父类, 初始化一些对象
13 | :param website: 名称
14 | :param browser: 浏览器, 若不使用浏览器则可设置为 None
15 | """
16 | self.website = website
17 | self.cookies_db = RedisClient('cookies', self.website)
18 | self.accounts_db = RedisClient('accounts', self.website)
19 | self.init_browser()
20 |
21 | def __del__(self):
22 | self.close()
23 |
24 | def init_browser(self):
25 | """
26 | 通过browser参数初始化全局浏览器供模拟登录使用
27 | :return:
28 | """
29 | if BROWSER_TYPE == 'PhantomJS':
30 | caps = DesiredCapabilities.PHANTOMJS
31 | caps[
32 | "phantomjs.page.settings.userAgent"] = 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/57.0.2987.133 Safari/537.36'
33 | self.browser = webdriver.PhantomJS(desired_capabilities=caps)
34 | self.browser.set_window_size(1400, 500)
35 | elif BROWSER_TYPE == 'Chrome':
36 | self.browser = webdriver.Chrome()
37 |
38 | def new_cookies(self, username, password):
39 | """
40 | 新生成Cookies,子类需要重写
41 | :param username: 用户名
42 | :param password: 密码
43 | :return:
44 | """
45 | raise NotImplementedError
46 |
47 | def process_cookies(self, cookies):
48 | """
49 | 处理Cookies
50 | :param cookies:
51 | :return:
52 | """
53 | dict = {}
54 | for cookie in cookies:
55 | dict[cookie['name']] = cookie['value']
56 | return dict
57 |
58 | def run(self):
59 | """
60 | 运行, 得到所有账户, 然后顺次模拟登录
61 | :return:
62 | """
63 | accounts_usernames = self.accounts_db.usernames()
64 | cookies_usernames = self.cookies_db.usernames()
65 |
66 | for username in accounts_usernames:
67 | if not username in cookies_usernames:
68 | password = self.accounts_db.get(username)
69 | print('正在生成Cookies', '账号', username, '密码', password)
70 | result = self.new_cookies(username, password)
71 | # 成功获取
72 | if result.get('status') == 1:
73 | cookies = self.process_cookies(result.get('content'))
74 | print('成功获取到Cookies', cookies)
75 | if self.cookies_db.set(username, json.dumps(cookies)):
76 | print('成功保存Cookies')
77 | # 密码错误,移除账号
78 | elif result.get('status') == 2:
79 | print(result.get('content'))
80 | if self.accounts_db.delete(username):
81 | print('成功删除账号')
82 | else:
83 | print(result.get('content'))
84 | else:
85 | print('所有账号都已经成功获取Cookies')
86 |
87 | def close(self):
88 | """
89 | 关闭
90 | :return:
91 | """
92 | try:
93 | print('Closing Browser')
94 | self.browser.close()
95 | del self.browser
96 | except TypeError:
97 | print('Browser not opened')
98 |
99 |
100 | class WeiboCookiesGenerator(CookiesGenerator):
101 | def __init__(self, website='weibo'):
102 | """
103 | 初始化操作
104 | :param website: 站点名称
105 | :param browser: 使用的浏览器
106 | """
107 | CookiesGenerator.__init__(self, website)
108 | self.website = website
109 |
110 | def new_cookies(self, username, password):
111 | """
112 | 生成Cookies
113 | :param username: 用户名
114 | :param password: 密码
115 | :return: 用户名和Cookies
116 | """
117 | return WeiboCookies(username, password, self.browser).main()
118 |
119 |
120 | if __name__ == '__main__':
121 | generator = WeiboCookiesGenerator()
122 | generator.run()
123 |
--------------------------------------------------------------------------------
/cookiespool/importer.py:
--------------------------------------------------------------------------------
1 | import requests
2 |
3 | from cookiespool.db import RedisClient
4 |
5 | conn = RedisClient('accounts', 'weibo')
6 |
7 | def set(account, sep='----'):
8 | username, password = account.split(sep)
9 | result = conn.set(username, password)
10 | print('账号', username, '密码', password)
11 | print('录入成功' if result else '录入失败')
12 |
13 |
14 | def scan():
15 | print('请输入账号密码组, 输入exit退出读入')
16 | while True:
17 | account = input()
18 | if account == 'exit':
19 | break
20 | set(account)
21 |
22 |
23 | if __name__ == '__main__':
24 | scan()
--------------------------------------------------------------------------------
/cookiespool/scheduler.py:
--------------------------------------------------------------------------------
1 | import time
2 | from multiprocessing import Process
3 |
4 | from cookiespool.api import app
5 | from cookiespool.config import *
6 | from cookiespool.generator import *
7 | from cookiespool.tester import *
8 |
9 |
10 | class Scheduler(object):
11 | @staticmethod
12 | def valid_cookie(cycle=CYCLE):
13 | while True:
14 | print('Cookies检测进程开始运行')
15 | try:
16 | for website, cls in TESTER_MAP.items():
17 | tester = eval(cls + '(website="' + website + '")')
18 | tester.run()
19 | print('Cookies检测完成')
20 | del tester
21 | time.sleep(cycle)
22 | except Exception as e:
23 | print(e.args)
24 |
25 | @staticmethod
26 | def generate_cookie(cycle=CYCLE):
27 | while True:
28 | print('Cookies生成进程开始运行')
29 | try:
30 | for website, cls in GENERATOR_MAP.items():
31 | generator = eval(cls + '(website="' + website + '")')
32 | generator.run()
33 | print('Cookies生成完成')
34 | generator.close()
35 | time.sleep(cycle)
36 | except Exception as e:
37 | print(e.args)
38 |
39 | @staticmethod
40 | def api():
41 | print('API接口开始运行')
42 | app.run(host=API_HOST, port=API_PORT)
43 |
44 | def run(self):
45 | if API_PROCESS:
46 | api_process = Process(target=Scheduler.api)
47 | api_process.start()
48 |
49 | if GENERATOR_PROCESS:
50 | generate_process = Process(target=Scheduler.generate_cookie)
51 | generate_process.start()
52 |
53 | if VALID_PROCESS:
54 | valid_process = Process(target=Scheduler.valid_cookie)
55 | valid_process.start()
56 |
--------------------------------------------------------------------------------
/cookiespool/tester.py:
--------------------------------------------------------------------------------
1 | import json
2 | import requests
3 | from requests.exceptions import ConnectionError
4 | from cookiespool.db import *
5 |
6 |
7 | class ValidTester(object):
8 | def __init__(self, website='default'):
9 | self.website = website
10 | self.cookies_db = RedisClient('cookies', self.website)
11 | self.accounts_db = RedisClient('accounts', self.website)
12 |
13 | def test(self, username, cookies):
14 | raise NotImplementedError
15 |
16 | def run(self):
17 | cookies_groups = self.cookies_db.all()
18 | for username, cookies in cookies_groups.items():
19 | self.test(username, cookies)
20 |
21 |
22 | class WeiboValidTester(ValidTester):
23 | def __init__(self, website='weibo'):
24 | ValidTester.__init__(self, website)
25 |
26 | def test(self, username, cookies):
27 | print('正在测试Cookies', '用户名', username)
28 | try:
29 | cookies = json.loads(cookies)
30 | except TypeError:
31 | print('Cookies不合法', username)
32 | self.cookies_db.delete(username)
33 | print('删除Cookies', username)
34 | return
35 | try:
36 | test_url = TEST_URL_MAP[self.website]
37 | response = requests.get(test_url, cookies=cookies, timeout=5, allow_redirects=False)
38 | if response.status_code == 200:
39 | print('Cookies有效', username)
40 | else:
41 | print(response.status_code, response.headers)
42 | print('Cookies失效', username)
43 | self.cookies_db.delete(username)
44 | print('删除Cookies', username)
45 | except ConnectionError as e:
46 | print('发生异常', e.args)
47 |
48 | if __name__ == '__main__':
49 | WeiboValidTester().run()
--------------------------------------------------------------------------------
/importer.py:
--------------------------------------------------------------------------------
1 | from cookiespool.importer import scan
2 |
3 | if __name__ == '__main__':
4 | scan()
--------------------------------------------------------------------------------
/login/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Python3WebSpider/CookiesPool/e724f8d19b17970e79f1a8b942ae943b6fcf12c2/login/__init__.py
--------------------------------------------------------------------------------
/login/weibo/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Python3WebSpider/CookiesPool/e724f8d19b17970e79f1a8b942ae943b6fcf12c2/login/weibo/__init__.py
--------------------------------------------------------------------------------
/login/weibo/cookies.py:
--------------------------------------------------------------------------------
1 | import time
2 | from io import BytesIO
3 | from PIL import Image
4 | from selenium.common.exceptions import TimeoutException
5 | from selenium.webdriver import ActionChains
6 | from selenium.webdriver.common.by import By
7 | from selenium.webdriver.support.ui import WebDriverWait
8 | from selenium.webdriver.support import expected_conditions as EC
9 | from os import listdir
10 | from os.path import abspath, dirname
11 |
12 | TEMPLATES_FOLDER = dirname(abspath(__file__)) + '/templates/'
13 |
14 |
15 | class WeiboCookies():
16 | def __init__(self, username, password, browser):
17 | self.url = 'https://passport.weibo.cn/signin/login?entry=mweibo&r=https://m.weibo.cn/'
18 | self.browser = browser
19 | self.wait = WebDriverWait(self.browser, 20)
20 | self.username = username
21 | self.password = password
22 |
23 | def open(self):
24 | """
25 | 打开网页输入用户名密码并点击
26 | :return: None
27 | """
28 | self.browser.delete_all_cookies()
29 | self.browser.get(self.url)
30 | username = self.wait.until(EC.presence_of_element_located((By.ID, 'loginName')))
31 | password = self.wait.until(EC.presence_of_element_located((By.ID, 'loginPassword')))
32 | submit = self.wait.until(EC.element_to_be_clickable((By.ID, 'loginAction')))
33 | username.send_keys(self.username)
34 | password.send_keys(self.password)
35 | time.sleep(1)
36 | submit.click()
37 |
38 | def password_error(self):
39 | """
40 | 判断是否密码错误
41 | :return:
42 | """
43 | try:
44 | return WebDriverWait(self.browser, 5).until(
45 | EC.text_to_be_present_in_element((By.ID, 'errorMsg'), '用户名或密码错误'))
46 | except TimeoutException:
47 | return False
48 |
49 | def login_successfully(self):
50 | """
51 | 判断是否登录成功
52 | :return:
53 | """
54 | try:
55 | return bool(
56 | WebDriverWait(self.browser, 5).until(EC.presence_of_element_located((By.CLASS_NAME, 'lite-iconf-profile'))))
57 | except TimeoutException:
58 | return False
59 |
60 | def get_position(self):
61 | """
62 | 获取验证码位置
63 | :return: 验证码位置元组
64 | """
65 | try:
66 | img = self.wait.until(EC.presence_of_element_located((By.CLASS_NAME, 'patt-shadow')))
67 | except TimeoutException:
68 | print('未出现验证码')
69 | self.open()
70 | time.sleep(2)
71 | location = img.location
72 | size = img.size
73 | top, bottom, left, right = location['y'], location['y'] + size['height'], location['x'], location['x'] + size[
74 | 'width']
75 | return (top, bottom, left, right)
76 |
77 | def get_screenshot(self):
78 | """
79 | 获取网页截图
80 | :return: 截图对象
81 | """
82 | screenshot = self.browser.get_screenshot_as_png()
83 | screenshot = Image.open(BytesIO(screenshot))
84 | return screenshot
85 |
86 | def get_image(self, name='captcha.png'):
87 | """
88 | 获取验证码图片
89 | :return: 图片对象
90 | """
91 | top, bottom, left, right = self.get_position()
92 | print('验证码位置', top, bottom, left, right)
93 | screenshot = self.get_screenshot()
94 | captcha = screenshot.crop((left, top, right, bottom))
95 | return captcha
96 |
97 | def is_pixel_equal(self, image1, image2, x, y):
98 | """
99 | 判断两个像素是否相同
100 | :param image1: 图片1
101 | :param image2: 图片2
102 | :param x: 位置x
103 | :param y: 位置y
104 | :return: 像素是否相同
105 | """
106 | # 取两个图片的像素点
107 | pixel1 = image1.load()[x, y]
108 | pixel2 = image2.load()[x, y]
109 | threshold = 20
110 | if abs(pixel1[0] - pixel2[0]) < threshold and abs(pixel1[1] - pixel2[1]) < threshold and abs(
111 | pixel1[2] - pixel2[2]) < threshold:
112 | return True
113 | else:
114 | return False
115 |
116 | def same_image(self, image, template):
117 | """
118 | 识别相似验证码
119 | :param image: 待识别验证码
120 | :param template: 模板
121 | :return:
122 | """
123 | # 相似度阈值
124 | threshold = 0.99
125 | count = 0
126 | for x in range(image.width):
127 | for y in range(image.height):
128 | # 判断像素是否相同
129 | if self.is_pixel_equal(image, template, x, y):
130 | count += 1
131 | result = float(count) / (image.width * image.height)
132 | if result > threshold:
133 | print('成功匹配')
134 | return True
135 | return False
136 |
137 | def detect_image(self, image):
138 | """
139 | 匹配图片
140 | :param image: 图片
141 | :return: 拖动顺序
142 | """
143 | for template_name in listdir(TEMPLATES_FOLDER):
144 | print('正在匹配', template_name)
145 | template = Image.open(TEMPLATES_FOLDER + template_name)
146 | if self.same_image(image, template):
147 | # 返回顺序
148 | numbers = [int(number) for number in list(template_name.split('.')[0])]
149 | print('拖动顺序', numbers)
150 | return numbers
151 |
152 | def move(self, numbers):
153 | """
154 | 根据顺序拖动
155 | :param numbers:
156 | :return:
157 | """
158 | # 获得四个按点
159 | try:
160 | circles = self.browser.find_elements_by_css_selector('.patt-wrap .patt-circ')
161 | dx = dy = 0
162 | for index in range(4):
163 | circle = circles[numbers[index] - 1]
164 | # 如果是第一次循环
165 | if index == 0:
166 | # 点击第一个按点
167 | ActionChains(self.browser) \
168 | .move_to_element_with_offset(circle, circle.size['width'] / 2, circle.size['height'] / 2) \
169 | .click_and_hold().perform()
170 | else:
171 | # 小幅移动次数
172 | times = 30
173 | # 拖动
174 | for i in range(times):
175 | ActionChains(self.browser).move_by_offset(dx / times, dy / times).perform()
176 | time.sleep(1 / times)
177 | # 如果是最后一次循环
178 | if index == 3:
179 | # 松开鼠标
180 | ActionChains(self.browser).release().perform()
181 | else:
182 | # 计算下一次偏移
183 | dx = circles[numbers[index + 1] - 1].location['x'] - circle.location['x']
184 | dy = circles[numbers[index + 1] - 1].location['y'] - circle.location['y']
185 | except:
186 | return False
187 |
188 | def get_cookies(self):
189 | """
190 | 获取Cookies
191 | :return:
192 | """
193 | return self.browser.get_cookies()
194 |
195 | def main(self):
196 | """
197 | 破解入口
198 | :return:
199 | """
200 | self.open()
201 | if self.password_error():
202 | return {
203 | 'status': 2,
204 | 'content': '用户名或密码错误'
205 | }
206 | # 如果不需要验证码直接登录成功
207 | if self.login_successfully():
208 | cookies = self.get_cookies()
209 | return {
210 | 'status': 1,
211 | 'content': cookies
212 | }
213 | # 获取验证码图片
214 | image = self.get_image('captcha.png')
215 | numbers = self.detect_image(image)
216 | self.move(numbers)
217 | if self.login_successfully():
218 | cookies = self.get_cookies()
219 | return {
220 | 'status': 1,
221 | 'content': cookies
222 | }
223 | else:
224 | return {
225 | 'status': 3,
226 | 'content': '登录失败'
227 | }
228 |
229 |
230 | if __name__ == '__main__':
231 | result = WeiboCookies('14773427930', 'x6pybpakq1').main()
232 | print(result)
233 |
--------------------------------------------------------------------------------
/login/weibo/templates/1234.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Python3WebSpider/CookiesPool/e724f8d19b17970e79f1a8b942ae943b6fcf12c2/login/weibo/templates/1234.png
--------------------------------------------------------------------------------
/login/weibo/templates/1243.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Python3WebSpider/CookiesPool/e724f8d19b17970e79f1a8b942ae943b6fcf12c2/login/weibo/templates/1243.png
--------------------------------------------------------------------------------
/login/weibo/templates/1324.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Python3WebSpider/CookiesPool/e724f8d19b17970e79f1a8b942ae943b6fcf12c2/login/weibo/templates/1324.png
--------------------------------------------------------------------------------
/login/weibo/templates/1342.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Python3WebSpider/CookiesPool/e724f8d19b17970e79f1a8b942ae943b6fcf12c2/login/weibo/templates/1342.png
--------------------------------------------------------------------------------
/login/weibo/templates/1423.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Python3WebSpider/CookiesPool/e724f8d19b17970e79f1a8b942ae943b6fcf12c2/login/weibo/templates/1423.png
--------------------------------------------------------------------------------
/login/weibo/templates/1432.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Python3WebSpider/CookiesPool/e724f8d19b17970e79f1a8b942ae943b6fcf12c2/login/weibo/templates/1432.png
--------------------------------------------------------------------------------
/login/weibo/templates/2134.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Python3WebSpider/CookiesPool/e724f8d19b17970e79f1a8b942ae943b6fcf12c2/login/weibo/templates/2134.png
--------------------------------------------------------------------------------
/login/weibo/templates/2143.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Python3WebSpider/CookiesPool/e724f8d19b17970e79f1a8b942ae943b6fcf12c2/login/weibo/templates/2143.png
--------------------------------------------------------------------------------
/login/weibo/templates/2314.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Python3WebSpider/CookiesPool/e724f8d19b17970e79f1a8b942ae943b6fcf12c2/login/weibo/templates/2314.png
--------------------------------------------------------------------------------
/login/weibo/templates/2341.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Python3WebSpider/CookiesPool/e724f8d19b17970e79f1a8b942ae943b6fcf12c2/login/weibo/templates/2341.png
--------------------------------------------------------------------------------
/login/weibo/templates/2413.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Python3WebSpider/CookiesPool/e724f8d19b17970e79f1a8b942ae943b6fcf12c2/login/weibo/templates/2413.png
--------------------------------------------------------------------------------
/login/weibo/templates/2431.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Python3WebSpider/CookiesPool/e724f8d19b17970e79f1a8b942ae943b6fcf12c2/login/weibo/templates/2431.png
--------------------------------------------------------------------------------
/login/weibo/templates/3124.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Python3WebSpider/CookiesPool/e724f8d19b17970e79f1a8b942ae943b6fcf12c2/login/weibo/templates/3124.png
--------------------------------------------------------------------------------
/login/weibo/templates/3142.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Python3WebSpider/CookiesPool/e724f8d19b17970e79f1a8b942ae943b6fcf12c2/login/weibo/templates/3142.png
--------------------------------------------------------------------------------
/login/weibo/templates/3214.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Python3WebSpider/CookiesPool/e724f8d19b17970e79f1a8b942ae943b6fcf12c2/login/weibo/templates/3214.png
--------------------------------------------------------------------------------
/login/weibo/templates/3241.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Python3WebSpider/CookiesPool/e724f8d19b17970e79f1a8b942ae943b6fcf12c2/login/weibo/templates/3241.png
--------------------------------------------------------------------------------
/login/weibo/templates/3412.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Python3WebSpider/CookiesPool/e724f8d19b17970e79f1a8b942ae943b6fcf12c2/login/weibo/templates/3412.png
--------------------------------------------------------------------------------
/login/weibo/templates/3421.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Python3WebSpider/CookiesPool/e724f8d19b17970e79f1a8b942ae943b6fcf12c2/login/weibo/templates/3421.png
--------------------------------------------------------------------------------
/login/weibo/templates/4123.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Python3WebSpider/CookiesPool/e724f8d19b17970e79f1a8b942ae943b6fcf12c2/login/weibo/templates/4123.png
--------------------------------------------------------------------------------
/login/weibo/templates/4132.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Python3WebSpider/CookiesPool/e724f8d19b17970e79f1a8b942ae943b6fcf12c2/login/weibo/templates/4132.png
--------------------------------------------------------------------------------
/login/weibo/templates/4213.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Python3WebSpider/CookiesPool/e724f8d19b17970e79f1a8b942ae943b6fcf12c2/login/weibo/templates/4213.png
--------------------------------------------------------------------------------
/login/weibo/templates/4231.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Python3WebSpider/CookiesPool/e724f8d19b17970e79f1a8b942ae943b6fcf12c2/login/weibo/templates/4231.png
--------------------------------------------------------------------------------
/login/weibo/templates/4312.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Python3WebSpider/CookiesPool/e724f8d19b17970e79f1a8b942ae943b6fcf12c2/login/weibo/templates/4312.png
--------------------------------------------------------------------------------
/login/weibo/templates/4321.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Python3WebSpider/CookiesPool/e724f8d19b17970e79f1a8b942ae943b6fcf12c2/login/weibo/templates/4321.png
--------------------------------------------------------------------------------
/requirements.txt:
--------------------------------------------------------------------------------
1 | requests>=2.13.0
2 | selenium>=3.4.0
3 | redis>=2.10.5
4 | Flask>=0.12.1
--------------------------------------------------------------------------------
/run.py:
--------------------------------------------------------------------------------
1 | from cookiespool.scheduler import Scheduler
2 |
3 | def main():
4 | s = Scheduler()
5 | s.run()
6 |
7 | if __name__ == '__main__':
8 | main()
--------------------------------------------------------------------------------