From 5a82462cace3e505e5442361b95db7c28f26e8c2 Mon Sep 17 00:00:00 2001 From: Qiea <1310371422@qq.com> Date: Sun, 22 Dec 2024 12:31:29 +0800 Subject: [PATCH] =?UTF-8?q?=E5=AE=8C=E5=96=84=E5=8A=9F=E8=83=BD=EF=BC=9A?= =?UTF-8?q?=E6=95=B0=E6=8D=AE=E5=BA=93=E8=B6=85=E6=97=B6=E7=AD=89=E5=BE=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 1 + README.md | 38 +++++++++++++++++++++-------- Thread.py | 71 ++++++++++++++++++++++++++++++++++++++++++------------ Tools.py | 13 +++++++--- config.cfg | 6 ++++- main.py | 14 ++++------- 6 files changed, 103 insertions(+), 40 deletions(-) diff --git a/.gitignore b/.gitignore index 2c4a966..768cdfe 100644 --- a/.gitignore +++ b/.gitignore @@ -160,3 +160,4 @@ cython_debug/ #.idea/ /.idea /img +/test.py diff --git a/README.md b/README.md index e831f1a..e7b0712 100644 --- a/README.md +++ b/README.md @@ -1,21 +1,39 @@ # GetQQInfo # 我超,盒 -# -### 本项目通过使用 {imagehash} 对比两个图片的相似度,从而实现通过头像获取QQ号 +## 项目简介 +本项目通过使用 `imagehash` 对比两个图片的相似度,从而实现通过头像获取 QQ 号。 -- type = 1 :通过Mysql数据库查询qq号 -- type = 2 :通过网络下载头像查询qq号 -- type = 3 :下载TargetRange范围内的qq号,解析每个qq号的头像后,上传Hash值到Mysql服务器 +## 功能说明 -### Mysql数据库配置: +- **type = 1**:通过 MySQL 数据库查询 QQ 号 +- **type = 2**:通过 网络下载头像查询 QQ 号 +- **type = 3**:下载 TargetRange 范围内的 QQ 号,解析每个 QQ 号的头像后,上传 Hash 值到 MySQL 服务器 + +## MySQL 数据库配置 +直接复制使用 ```mysql -CREATE TABLE example ( - id INT unsigned AUTO_INCREMENT PRIMARY KEY, - hash TINYBLOB NULL +-- 如果数据库 qqinfo 不存在,则创建它 +CREATE DATABASE IF NOT EXISTS qqinfo; + +-- 选择使用 qqinfo 数据库 +USE qqinfo; + +-- 创建一个名为 image_hashes 的表,存储图像的哈希值 +CREATE TABLE image_hashes ( + id INT unsigned AUTO_INCREMENT PRIMARY KEY, -- 自增主键,确保每行唯一 + hash TINYBLOB NULL -- 存储图片的哈希值,类型为 TINYBLOB,可以为空 ); + ``` +## 头像下载地址 -头像下载地址:https://q1.qlogo.cn/g?b=qq&nk=114514&s=0 \ No newline at end of file +[点击这里下载头像](https://q1.qlogo.cn/g?b=qq&nk=114514&s=0) + + +### 主要改动: +1. 添加了“项目简介”和“功能说明”小节,提升可读性。 +2. 用粗体加粗了功能描述的关键字(`type = 1`、`type = 2`、`type = 3`),突出重要信息。 +3. 在“头像下载地址”部分,增加了链接的描述文字,使得链接更易理解。 \ No newline at end of file diff --git a/Thread.py b/Thread.py index 562f4ec..2f8a227 100644 --- a/Thread.py +++ b/Thread.py @@ -1,20 +1,60 @@ -import pymysql, threading +import pymysql, threading, time +from queue import Queue from Tools import config, download_image, Hash, remove_image, compare, Image, imagehash, os, logging, clean_image -Myconn = pymysql.connect( - host=str(config['mysql']['host']), - user=str(config['mysql']['user']), - password=str(config['mysql']['password']), - database=str(config['mysql']['database']) - ) +class MySQLConnectionPool: + def __init__(self): + self.pool_size = int(config['mysql']['pool_size']) + self.pool = Queue(maxsize=self.pool_size) + self.host = str(config['mysql']['host']) + self.user = str(config['mysql']['user']) + self.password = str(config['mysql']['password']) + self.database = str(config['mysql']['database']) + + # 初始化连接池 + for _ in range(self.pool_size): + conn = pymysql.connect( + host=self.host, + user=self.user, + password=self.password, + database=self.database, + cursorclass=pymysql.cursors.DictCursor + ) + self.pool.put(conn) + + import time + + def get_connection(self, max_retries=5, wait_time=1): + """获取一个数据库连接,如果连接池为空,继续尝试直到能够获取连接""" + retries = 0 + while retries < max_retries: + if not self.pool.empty(): + return self.pool.get() + else: + retries += 1 + print(f"连接池中没有可用连接,正在尝试第 {retries} 次连接...") + time.sleep(wait_time) # 等待指定时间再尝试 + + raise Exception("连接池中没有可用连接,已尝试多次连接") + + def release_connection(self, conn): + """释放数据库连接""" + if conn: + self.pool.put(conn) + + def close_all(self): + """关闭所有连接""" + while not self.pool.empty(): + conn = self.pool.get() + conn.close() -exit_flag = False class UploadThread(threading.Thread): - def __init__(self, uploadqqnumber): + def __init__(self, uploadqqnumber, pool): super().__init__() self.uploadqqnumber = uploadqqnumber - self.conn = Myconn + self.pool = pool + self.conn = pool.get_connection() def run(self): @@ -23,24 +63,23 @@ class UploadThread(threading.Thread): Hash(self.conn).tomysql(self.uploadqqnumber) logging.info(f'上传成功: {self.uploadqqnumber}') remove_image(self.uploadqqnumber) - self.conn.close() + self.pool.release_connection(self.conn) class FindThread(threading.Thread): - def __init__(self, TargetImageHash): + def __init__(self, TargetImageHash, pool): super().__init__() self.TargetImageHash = TargetImageHash - self.conn = Myconn + self.pool = pool + self.conn = pool.get_connection() def run(self): - global exit_flag logging.debug(f'我是查询线程{self.TargetImageHash}') res = Hash(self.conn).getqq(self.TargetImageHash) if res != 'error': logging.info(f'查询成功,QQ号是: {res}') - exit_flag = True - self.conn.close() + self.pool.release_connection(self.conn) diff --git a/Tools.py b/Tools.py index 89f020b..fc92da9 100644 --- a/Tools.py +++ b/Tools.py @@ -61,11 +61,16 @@ class Hash: _byte_data = bytes.fromhex(str(imagehash.average_hash(_img))) _cursor = self.conn.cursor() _cursor.execute(""" - INSERT INTO image_hashes (id, hash) + INSERT INTO `{}` (`{}`, `{}`) VALUES (%s, %s) - ON DUPLICATE KEY UPDATE - hash = VALUES(hash) - """, (_qqnumber, _byte_data)) + ON DUPLICATE KEY UPDATE `{}` = VALUES(`{}`) + """.format( + config['mysql']['table_name'], + config['mysql']['id_column_name'], + config['mysql']['hash_column_name'], + config['mysql']['hash_column_name'], + config['mysql']['hash_column_name'] + ), (_qqnumber, _byte_data)) logging.debug(f'[{_qqnumber}]:{_byte_data}') self.conn.commit() _cursor.close() diff --git a/config.cfg b/config.cfg index 64c1bb9..9024679 100644 --- a/config.cfg +++ b/config.cfg @@ -1,5 +1,5 @@ [settings] -type = 2 +type = 3 TargetRange = 1310371400, 1310379530 TargetImage = ./img/target5.jpg @@ -8,6 +8,10 @@ host = 192.168.9.1 user = root password = 123456 database = qqinfo +table_name = image_hashes +id_column_name = id +hash_column_name = hash +pool_size = 100 [logging] level = 20 diff --git a/main.py b/main.py index 1853069..23ff905 100644 --- a/main.py +++ b/main.py @@ -1,4 +1,4 @@ -from Thread import UploadThread, FindThread, ByNetFindThread +from Thread import UploadThread, FindThread, ByNetFindThread, MySQLConnectionPool from Tools import imagehash, Image, os, config type = int(config['settings']['type']) @@ -12,8 +12,10 @@ if not os.path.exists('img'): if __name__ == '__main__': + pool = MySQLConnectionPool() + if type == 1: - Thread = FindThread(TargetImageHash) + Thread = FindThread(TargetImageHash, pool) Thread.start() elif type == 2: @@ -24,12 +26,6 @@ if __name__ == '__main__': elif type == 3: while baseArr <= TargetRange[1]: - Thread = UploadThread(baseArr) - Thread.start() - baseArr += 1 - Thread = UploadThread(baseArr) - Thread.start() - baseArr += 1 - Thread = UploadThread(baseArr) + Thread = UploadThread(baseArr, pool) Thread.start() baseArr += 1