完善功能:数据库超时等待

This commit is contained in:
Qiea
2024-12-22 12:31:29 +08:00
parent 1d534be4c1
commit 5a82462cac
6 changed files with 103 additions and 40 deletions

1
.gitignore vendored
View File

@@ -160,3 +160,4 @@ cython_debug/
#.idea/ #.idea/
/.idea /.idea
/img /img
/test.py

View File

@@ -1,21 +1,39 @@
# GetQQInfo # 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 ```mysql
CREATE TABLE example ( -- 如果数据库 qqinfo 不存在,则创建它
id INT unsigned AUTO_INCREMENT PRIMARY KEY, CREATE DATABASE IF NOT EXISTS qqinfo;
hash TINYBLOB NULL
-- 选择使用 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 [点击这里下载头像](https://q1.qlogo.cn/g?b=qq&nk=114514&s=0)
### 主要改动:
1. 添加了“项目简介”和“功能说明”小节,提升可读性。
2. 用粗体加粗了功能描述的关键字(`type = 1``type = 2``type = 3`),突出重要信息。
3. 在“头像下载地址”部分,增加了链接的描述文字,使得链接更易理解。

View File

@@ -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 from Tools import config, download_image, Hash, remove_image, compare, Image, imagehash, os, logging, clean_image
Myconn = pymysql.connect( class MySQLConnectionPool:
host=str(config['mysql']['host']), def __init__(self):
user=str(config['mysql']['user']), self.pool_size = int(config['mysql']['pool_size'])
password=str(config['mysql']['password']), self.pool = Queue(maxsize=self.pool_size)
database=str(config['mysql']['database']) 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): class UploadThread(threading.Thread):
def __init__(self, uploadqqnumber): def __init__(self, uploadqqnumber, pool):
super().__init__() super().__init__()
self.uploadqqnumber = uploadqqnumber self.uploadqqnumber = uploadqqnumber
self.conn = Myconn self.pool = pool
self.conn = pool.get_connection()
def run(self): def run(self):
@@ -23,24 +63,23 @@ class UploadThread(threading.Thread):
Hash(self.conn).tomysql(self.uploadqqnumber) Hash(self.conn).tomysql(self.uploadqqnumber)
logging.info(f'上传成功: {self.uploadqqnumber}') logging.info(f'上传成功: {self.uploadqqnumber}')
remove_image(self.uploadqqnumber) remove_image(self.uploadqqnumber)
self.conn.close() self.pool.release_connection(self.conn)
class FindThread(threading.Thread): class FindThread(threading.Thread):
def __init__(self, TargetImageHash): def __init__(self, TargetImageHash, pool):
super().__init__() super().__init__()
self.TargetImageHash = TargetImageHash self.TargetImageHash = TargetImageHash
self.conn = Myconn self.pool = pool
self.conn = pool.get_connection()
def run(self): def run(self):
global exit_flag
logging.debug(f'我是查询线程{self.TargetImageHash}') logging.debug(f'我是查询线程{self.TargetImageHash}')
res = Hash(self.conn).getqq(self.TargetImageHash) res = Hash(self.conn).getqq(self.TargetImageHash)
if res != 'error': if res != 'error':
logging.info(f'查询成功QQ号是: {res}') logging.info(f'查询成功QQ号是: {res}')
exit_flag = True self.pool.release_connection(self.conn)
self.conn.close()

View File

@@ -61,11 +61,16 @@ class Hash:
_byte_data = bytes.fromhex(str(imagehash.average_hash(_img))) _byte_data = bytes.fromhex(str(imagehash.average_hash(_img)))
_cursor = self.conn.cursor() _cursor = self.conn.cursor()
_cursor.execute(""" _cursor.execute("""
INSERT INTO image_hashes (id, hash) INSERT INTO `{}` (`{}`, `{}`)
VALUES (%s, %s) VALUES (%s, %s)
ON DUPLICATE KEY UPDATE ON DUPLICATE KEY UPDATE `{}` = VALUES(`{}`)
hash = VALUES(hash) """.format(
""", (_qqnumber, _byte_data)) 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}') logging.debug(f'[{_qqnumber}]:{_byte_data}')
self.conn.commit() self.conn.commit()
_cursor.close() _cursor.close()

View File

@@ -1,5 +1,5 @@
[settings] [settings]
type = 2 type = 3
TargetRange = 1310371400, 1310379530 TargetRange = 1310371400, 1310379530
TargetImage = ./img/target5.jpg TargetImage = ./img/target5.jpg
@@ -8,6 +8,10 @@ host = 192.168.9.1
user = root user = root
password = 123456 password = 123456
database = qqinfo database = qqinfo
table_name = image_hashes
id_column_name = id
hash_column_name = hash
pool_size = 100
[logging] [logging]
level = 20 level = 20

14
main.py
View File

@@ -1,4 +1,4 @@
from Thread import UploadThread, FindThread, ByNetFindThread from Thread import UploadThread, FindThread, ByNetFindThread, MySQLConnectionPool
from Tools import imagehash, Image, os, config from Tools import imagehash, Image, os, config
type = int(config['settings']['type']) type = int(config['settings']['type'])
@@ -12,8 +12,10 @@ if not os.path.exists('img'):
if __name__ == '__main__': if __name__ == '__main__':
pool = MySQLConnectionPool()
if type == 1: if type == 1:
Thread = FindThread(TargetImageHash) Thread = FindThread(TargetImageHash, pool)
Thread.start() Thread.start()
elif type == 2: elif type == 2:
@@ -24,12 +26,6 @@ if __name__ == '__main__':
elif type == 3: elif type == 3:
while baseArr <= TargetRange[1]: while baseArr <= TargetRange[1]:
Thread = UploadThread(baseArr) Thread = UploadThread(baseArr, pool)
Thread.start()
baseArr += 1
Thread = UploadThread(baseArr)
Thread.start()
baseArr += 1
Thread = UploadThread(baseArr)
Thread.start() Thread.start()
baseArr += 1 baseArr += 1