-
Notifications
You must be signed in to change notification settings - Fork 2
/
main.py
1649 lines (1507 loc) · 118 KB
/
main.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
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
# -*- coding: utf-8 -*-
import re
import uuid
import random
import requests
import base64
import PySimpleGUI as sg
import json
import os
import threading
from time import sleep
import time
import pymysql
import io
from io import BytesIO
import win32con
import win32clipboard as clip
from PIL import Image
from base64 import b64decode
import pandas as pd
from lxml import etree
from qcloud_cos import CosConfig
from qcloud_cos import CosS3Client
import warnings
warnings.filterwarnings("ignore")
line_boxes = b'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'
ECS_url = "http://" + "47.100.241.214" + ":8866/predict/ocr_system"
# 知乎图片爬取模块
pic = r"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"
class Answer(object):
def __init__(self):
self.id = ""
self.url = ""
self.response = None
self.author = ""
self.picURLList = []
class User(object):
def __init__(self, cookie):
self.Cookie = cookie
self.user_agent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.198 Safari/537.36"
self.headers = {
"user-agent": self.user_agent
}
if not cookie == None:
self.headers["cookie"] = self.Cookie
self.session = requests.session()
self.session.headers = self.headers
self.currentBrowseAnswer = Answer()
def getZhiHuAnswerWeb(self):
while True:
try:
response = self.session.get(url=self.currentBrowseAnswer.url)
break
except:
print(time.strftime(
"[%Y-%m-%d %H:%M:%S]: ", time.localtime()), "获取回答页面超时,有可能IP被知乎禁了,等待30秒再继续...")
sleep(30)
return response
def getAnswerAuthor(self):
try:
content = self.currentBrowseAnswer.response.text
HTML = etree.HTML(content)
author = HTML.xpath(
'//div[@class="Card AnswerCard"]//div[@class="AuthorInfo-content"]/div[@class="AuthorInfo-head"]//a[@class="UserLink-link"]/text()')[
0]
except:
return 'AnonymousUser'
return author
def extractPicURL(self, author):
content = self.currentBrowseAnswer.response.text
HTML = etree.HTML(content)
picURLList = HTML.xpath(
'//div[@class="Card AnswerCard"]//div[@class="RichContent-inner"]/span/figure/img/@data-original')
print(time.strftime(
"[%Y-%m-%d %H:%M:%S]: ", time.localtime()), '答主:“%s” 一共有 %d 个表情包,开始爬取!' % (author, len(picURLList)))
return picURLList
def downloadPicList(self, path, window):
'''多线程
global zhihu_cnt
zhihu_cnt = 0
for i in range(3):
print(time.strftime("[%Y-%m-%d %H:%M:%S]: ", time.localtime()), "第 %d 下载线程开启!" % (i + 1))
threading.Thread(target=self.thread_download, args=(
path, i+1, self.currentBrowseAnswer.picURLList, window)).start()
sleep(1)
'''
cnt = 0
for url in self.currentBrowseAnswer.picURLList:
filename = os.path.basename(url)
filename = filename[::-1][filename[::-1].index("?") + 1:][::-1]
if os.path.exists(path + self.currentBrowseAnswer.id + "@" + filename):
print(time.strftime(
"[%Y-%m-%d %H:%M:%S]: ", time.localtime()), '图片 %s 已存在!' % (self.currentBrowseAnswer.id + "@" + filename))
cnt += 1
continue
window['OUTPUT_3'].update(value=time.strftime(
"[%Y-%m-%d %H:%M:%S]: ", time.localtime()) + '正在下载第 %d / %d 张:%s' % (cnt+1, len(self.currentBrowseAnswer.picURLList), self.currentBrowseAnswer.id + "@" + filename))
# print(time.strftime(
# "[%Y-%m-%d %H:%M:%S]: ", time.localtime()), '正在下载第 %d / %d 张:%s' % (cnt+1, len(self.currentBrowseAnswer.picURLList), self.currentBrowseAnswer.id + "@" + filename))
self.downloadPic(url, path)
cnt += 1
window['-ZHIHUPROGRESS-'].update_bar(100 /
len(self.currentBrowseAnswer.picURLList) * cnt)
window['-ZHIHUPROGRESS_NUM-'].update(
str(cnt/len(self.currentBrowseAnswer.picURLList) * 100) + "%%")
sleep(0.8)
# def thread_download(self, path, slice, picURLList, window):
# global zhihu_cnt
# global zhihu_starttime
# for url in picURLList[len(picURLList)//6 * (slice - 1): len(picURLList)//6 * (slice)]:
# filename = os.path.basename(url)
# filename = filename[::-1][filename[::-1].index("?") + 1:][::-1]
# if os.path.exists(path + self.currentBrowseAnswer.id + "@" + filename):
# print(time.strftime(
# "[%Y-%m-%d %H:%M:%S]: ", time.localtime()), '图片 %s 已存在!' % (self.currentBrowseAnswer.id + "@" + filename))
# window['-ZHIHUPROGRESS-'].update_bar(
# 100 / len(picURLList) * zhihu_cnt)
# window['-ZHIHUPROGRESS_NUM-'].update(
# str(zhihu_cnt/len(picURLList) * 100) + "%%")
# zhihu_cnt += 1
# continue
# print(time.strftime(
# "[%Y-%m-%d %H:%M:%S]: ", time.localtime()), '第 %d 线程,正在下载第 %d / %d 张:%s' % (slice, zhihu_cnt+1, len(picURLList), self.currentBrowseAnswer.id + "@" + filename))
# self.downloadPic(slice, url, path)
# zhihu_cnt += 1
# window['-ZHIHUPROGRESS-'].update_bar(100 /
# len(picURLList) * zhihu_cnt)
# window['-ZHIHUPROGRESS_NUM-'].update(
# str(zhihu_cnt/len(picURLList) * 100) + "%%")
# sleep(2)
# if zhihu_cnt == len(picURLList):
# elapse = time.time() - zhihu_starttime
# print(time.strftime(
# "[%Y-%m-%d %H:%M:%S]: ", time.localtime()), "爬取完毕,一共耗时:%.3fs!" % (elapse))
def downloadPic(self, url, path):
filename = os.path.basename(url)
filename = filename[::-1][filename[::-1].index("?") + 1:][::-1]
while True:
try:
pic = self.session.get(url, timeout=5).content
break
except:
print(time.strftime("[%Y-%m-%d %H:%M:%S]: ", time.localtime()),
"获取表情包:%s 超时,有可能IP被知乎禁了,等待5秒再继续..." % ( filename))
sleep(5)
with open(path + self.currentBrowseAnswer.id + "@" + filename, "wb") as f:
f.write(pic)
# 知乎图片爬取模块
def CopyIP(window, value):
txt = value
clip.OpenClipboard() # 打开剪贴板
clip.EmptyClipboard() # 先清空剪贴板
clip.SetClipboardData(win32con.CF_UNICODETEXT, txt) # 将IP放入剪贴板
clip.CloseClipboard()
# 原版登录用户统计方案
# def OnlineUserNumber(window):
# global flag
# old = []
# sleep(3)
# while True:
# try:
# while True:
# try:
# conn = pymysql.connect(
# '47.96.189.80', user="root", passwd="189154", db="EmojiPic")
# break
# except:
# print(time.strftime(
# "[%Y-%m-%d %H:%M:%S]: ", time.localtime()), '获取用户数失败,重连数据库中...')
# try:
# conn.close()
# except:
# pass
# cursor = conn.cursor()
# cursor.execute(
# "select SUBSTRING_INDEX(host,':',1) as ip , count(*) from information_schema.processlist group by ip;")
# res = cursor.fetchall()
# number = len(res)
# ip = [u[0] for u in res]
# for user in ip:
# if user not in old:
# print(time.strftime(
# "[%Y-%m-%d %H:%M:%S]: ", time.localtime()), '用户:%s 开始了TA的斗图之旅。' % (user))
# old.append(user)
# for o in old:
# if o not in ip:
# print(time.strftime(
# "[%Y-%m-%d %H:%M:%S]: ", time.localtime()), '用户:%s 圆满地结束了TA的斗图之旅。' % (o))
# old.remove(o)
# window['-USERNUM-'].update(number)
# if flag == 0:
# cursor.close()
# while True:
# try:
# conn.close()
# except:
# break
# break
# sleep(2)
# except:
# break
def UpdateEmojiNumber(window):
global flag
while True:
try:
while True:
try:
conn = pymysql.connect(
'47.96.189.80', user="root", passwd="189154", db="EmojiPic")
break
except:
print(time.strftime(
"[%Y-%m-%d %H:%M:%S]: ", time.localtime()), '重连数据库中...')
try:
conn.close()
except:
pass
cursor = conn.cursor()
cursor.execute("SELECT count(*) FROM EMOJITEXT")
res = cursor.fetchone()
number = res[0]
# window['-EMOJINUM-'].update(res[0])
cursor.close()
conn.close()
sleep(3)
while True:
try:
conn = pymysql.connect(
'47.96.189.80', user="root", passwd="189154", db="EmojiPic")
break
except:
print(time.strftime(
"[%Y-%m-%d %H:%M:%S]: ", time.localtime()), '重连数据库中...')
try:
conn.close()
except:
pass
cursor = conn.cursor()
cursor.execute("SELECT count(*) FROM EMOJITEXT")
res = cursor.fetchone()
if number < res[0]:
print(time.strftime(
"[%Y-%m-%d %H:%M:%S]: ", time.localtime()), '数据库表情包数量增加了:%d' % (res[0] - number))
elif number > res[0]:
print(time.strftime(
"[%Y-%m-%d %H:%M:%S]: ", time.localtime()), '数据库表情包数量减少了:%d' % (number - res[0]))
number = res[0]
window['-EMOJINUM-'].update(res[0])
if flag == 0:
cursor.close()
while True:
try:
conn.close()
except:
break
break
sleep(2)
except:
break
def cv2_to_base64(image):
return base64.b64encode(image).decode('utf8')
def COSUploadAndRecognize(window, path):
path = path + '/'
path = path.replace('/', '//')
url = 'https://stickers-1259799643.cos.ap-shanghai.myqcloud.com/'
secret_id = 'AKIDUjnjR2sdTUGm6Bjcy47x1zlIchz1KKgu' # 替换为用户的secret_id
secret_key = 'AJFvMYWFm4T1KNCmfIfqoXO3YooY3C8C' # 替换为用户的secret_key
region = 'ap-shanghai' # 替换为地区参https://www.qcloud.com/document/product/436/6224的地简称
token = None # 使用临时秘钥需要传入Token,默认为空,可不填
config = CosConfig(Region=region, SecretId=secret_id,
SecretKey=secret_key, Token=token) # 获取配置对象
client = CosS3Client(config)
pics = os.listdir(path)
Exist = []
if os.path.exists(path + 'history.txt'):
with open(path + 'history.txt', 'r+') as f:
lines = f.readlines()
for line in lines:
Exist.append(line.replace("\n", ""))
f.close()
print(time.strftime("[%Y-%m-%d %H:%M:%S]: ", time.localtime()),
"目录:“%s” 一共有 %d 个文件!" % (path, len(pics)))
url_list = []
i = 1
starttime = time.time()
img_end = {'jpg', 'bmp', 'png', 'jpeg', 'rgb', 'tif', 'tiff', 'gif', 'GIF'}
try:
pics = [pic for pic in pics if pic.split('.')[-1] in img_end]
except:
print(time.strftime("[%Y-%m-%d %H:%M:%S]: ",
time.localtime()), "目录:%s 含有没有后缀的文件,直接过滤掉!" % (path))
pics = [pic for pic in pics if '.' in pic]
pics = [pic for pic in pics if pic.split('.')[-1] in img_end]
print(time.strftime("[%Y-%m-%d %H:%M:%S]: ",
time.localtime()), "过滤掉非图片文件后,一共有 %d 个图片!" % (len(pics)))
pic_num = len(pics)
for pic in pics:
if pic not in Exist:
window['OUTPUT_1'].update(value=time.strftime("[%Y-%m-%d %H:%M:%S]: ", time.localtime()) +
'正在上传:第 %d / %d 张图片:%s' % (i, len(pics), pic))
# print(time.strftime("[%Y-%m-%d %H:%M:%S]: ", time.localtime()),
# '正在上传:第 %d / %d 张图片:%s' % (i, len(pics), pic))
upload_cnt = 0
while True:
try:
response = client.upload_file(
Bucket='stickers-1259799643', # 空间名称自行更改
LocalFilePath=path + pic,
Key=pic,
PartSize=10,
MAXThread=10
)
url_list.append(url + pic)
break
except:
print(time.strftime("[%Y-%m-%d %H:%M:%S]: ", time.localtime()),
'%s 上传出错,可能重复,等待10s,重新上传!第 %d 次' % (pic, upload_cnt+1))
upload_cnt += 1
if upload_cnt == 3:
break
sleep(10)
window['-UPLOADPROGRESS-'].update_bar(100/pic_num * i)
window['-UPLOADPROGRESS_NUM-'].update(str(i/pic_num * 100) + "%%")
i += 1
with open(path + 'history.txt', 'a+') as f:
f.writelines(pic)
f.writelines('\n')
f.close()
else:
# print(time.strftime("[%Y-%m-%d %H:%M:%S]: ",
# time.localtime()), "正在上传:第 %d / %d 张图片:%s 已经上传过" % (i, len(pics), pic))
window['OUTPUT_1'].update(value=time.strftime("[%Y-%m-%d %H:%M:%S]: ",
time.localtime()) + "正在上传:第 %d / %d 张图片:%s 已经上传过" % (i, len(pics), pic))
window['-UPLOADPROGRESS-'].update_bar(100/pic_num * i)
window['-UPLOADPROGRESS_NUM-'].update(str(i/pic_num * 100) + "%%")
i += 1
elapse = time.time() - starttime
print(time.strftime("[%Y-%m-%d %H:%M:%S]: ", time.localtime()),
"一共上传了 %d 张表情包!耗时:%.3fs" % (i-1, elapse))
# file = {'smfile': open(path + pic, 'rb')}
# print(time.strftime("[%Y-%m-%d %H:%M:%S]: ", time.localtime()), '正在上传图片:%s' % (pic))
# while True:
# try:
# res = requests.post(url, files=file, headers=headers).json()
# break
# except:
# print(time.strftime("[%Y-%m-%d %H:%M:%S]: ", time.localtime()), '%s 上传超时,等待20s,重新上传!' % (pic))
# sleep(20)
# window['-UPLOADPROGRESS-'].update_bar(100/pic_num * i)
# window['-UPLOADPROGRESS_NUM-'].update(str(i/pic_num * 100) + "%%")
# i += 1
# try:
# url_list.append(res['data']['url'])
# except:
# print(time.strftime("[%Y-%m-%d %H:%M:%S]: ",
# time.localtime()), '%s 已经上传过!' % (pic))
# error_pic.append(pic)
# sleep(0.5)
# error_cnt = 1
# for p in error_pic:
# file = {'smfile': open(path + p, 'rb')}
# print(time.strftime("[%Y-%m-%d %H:%M:%S]: ", time.localtime()),
# '重新上传:%s 第%d/%d张' % (p, error_cnt, len(error_pic)))
# res = requests.post(url, files=file, headers=headers).json()
# error_cnt += 1
# try:
# url_list.append(res['data']['url'])
# except:
# print(time.strftime("[%Y-%m-%d %H:%M:%S]: ",
# time.localtime()), '%s 依旧上传失败!' % (p))
print(time.strftime("[%Y-%m-%d %H:%M:%S]: ", time.localtime()), '开始识别!')
server_url = ECS_url
server_headers = {"Content-type": "application/json"}
cnt = 0
total_time = 0
actual_pic_num = len(url_list)
for url in url_list:
name = url.split('/')[-1]
while True:
try:
r = requests.get(url,timeout=15)
break
except:
print(time.strftime("[%Y-%m-%d %H:%M:%S]: ",
time.localtime()), 'IP被COS禁了,睡眠0.5分钟!')
sleep(20)
try:
img = Image.open(BytesIO(r.content))
img_bytes = io.BytesIO()
img.save(img_bytes, format="JPEG")
img = img_bytes.getvalue()
except:
print(time.strftime("[%Y-%m-%d %H:%M:%S]: ",
time.localtime()), '图片 %s 无法读取,可能不是jpg文件!' % (name))
continue
if img is None:
print("error in loading image:{}".format(img))
continue
# 发送HTTP请求
starttime = time.time()
data = {'images': [cv2_to_base64(img)]}
try:
r = requests.post(url=server_url, headers=server_headers,
data=json.dumps(data), timeout=30)
except:
print(time.strftime("[%Y-%m-%d %H:%M:%S]: ",
time.localtime()), "%s 识别时,服务器长时间未响应!" % (name))
continue
elapse = time.time() - starttime
total_time += elapse
print(time.strftime("[%Y-%m-%d %H:%M:%S]: ", time.localtime()),
"识别了 第 %d / %d 张图片: %s, 识别时间 %.3fs" % (cnt+1, actual_pic_num, name, elapse))
try:
res = r.json()["results"][0]
except:
print(time.strftime("[%Y-%m-%d %H:%M:%S]: ",
time.localtime()), "%s 没有识别结果。" % (name))
cnt += 1
continue
text = ' '
for i in res:
text = text + i['text']
print(time.strftime("[%Y-%m-%d %H:%M:%S]: ",
time.localtime()), "插入数据库:%s: %s " % (name, text))
try:
while True:
try:
conn = pymysql.connect(
'47.96.189.80', user="root", passwd="189154", db="EmojiPic")
break
except:
print(time.strftime(
"[%Y-%m-%d %H:%M:%S]: ", time.localtime()), '重连数据库中...')
try:
conn.close()
except:
pass
cur = conn.cursor()
sql = "insert into EMOJITEXT values(%s,%s)"
cur.executemany(sql, [(url, text)])
cur.close()
conn.commit()
conn.close()
except:
print(time.strftime("[%Y-%m-%d %H:%M:%S]: ",
time.localtime()), "图片已存在数据库,跳过: %s" % (name))
try:
conn.close()
except:
pass
cnt += 1
window['-RECPROGRESS-'].update_bar(100/actual_pic_num * cnt)
window['-RECPROGRESS_NUM-'].update(str(cnt /
actual_pic_num * 100) + "%%")
try:
print(time.strftime("[%Y-%m-%d %H:%M:%S]: ", time.localtime()),
"平均识别时间: {}".format(float(total_time) / cnt))
print(time.strftime("[%Y-%m-%d %H:%M:%S]: ", time.localtime()),
"总共识别时间: {}".format(float(total_time)))
except:
pass
print(time.strftime("[%Y-%m-%d %H:%M:%S]: ",
time.localtime()), "总共识别了 %d 张表情包" % (cnt))
def CloudSearch(window, key):
print(time.strftime("[%Y-%m-%d %H:%M:%S]: ", time.localtime()), "开启多线程搜索!")
for i in range(300):
window['-IMG%s-' % (str(i+1))].update(data=None)
while True:
try:
conn = pymysql.connect(
'47.96.189.80', user="root", passwd="189154", db="EmojiPic")
break
except:
print(time.strftime("[%Y-%m-%d %H:%M:%S]: ",
time.localtime()), '重连数据库中...')
try:
conn.close()
except:
pass
cur = conn.cursor()
if ',' in key: # 只要包含其中一个
key_list = key.split(',')
key_set = set()
key_set_text = set()
for k in key_list:
cur.execute(
"select * from EMOJITEXT where locate('%s',text);" % (k))
resTuple = cur.fetchall()
for r in resTuple:
key_set.add(r[0])
key_set_text.add(r[1])
elif ';' in key: # 全都包含
key_list = key.split(';')
key_intersection = []
key_intersection_text = []
key_cnt = 0
for k in key_list:
cur.execute(
"select * from EMOJITEXT where locate('%s',text);" % (k))
resTuple = cur.fetchall()
resList = [r[0] for r in resTuple]
resList_text = [r[1] for r in resTuple]
if key_cnt == 0:
key_intersection = resList
key_intersection_text = resList_text
else:
key_intersection = list(set(key_intersection).intersection(resList))
key_intersection_text = list(set(key_intersection_text).intersection(resList_text))
key_cnt += 1
key_set = key_intersection
key_set_text = key_intersection_text
else:
key_set = set()
key_set_text = set()
cur.execute("select * from EMOJITEXT where locate('%s',text);" % (key))
resTuple = cur.fetchall()
for r in resTuple:
key_set.add(r[0])
key_set_text.add(r[1])
print(time.strftime("[%Y-%m-%d %H:%M:%S]: ", time.localtime()),
"关键字:'%s' 云端一共找到 %d 张表情包!正在展示,速度与网速有关。" % (key, len(key_set)))
if len(key_set) == 0:
print(time.strftime("[%Y-%m-%d %H:%M:%S]: ",
time.localtime()), "赶紧上传点表情包吧,已经不够你秀的了!")
return
cur.close()
conn.close()
global thread_cnt
global end_flag
global Search_starttime
thread_cnt = 0
end_flag = 0
key_set = list(key_set)
key_set_text = list(key_set_text)
s = requests.session()
s.keep_alive = False
Search_starttime = time.time()
threading.Thread(target=ThreadPrint,
args=(key_set,window,key_set_text)).start()
threading.Thread(target=CloudSearchThread,
args=(1, key_set, window, 0)).start()
# print(time.strftime("[%Y-%m-%d %H:%M:%S]: ", time.localtime()), "开启第1线程!")
threading.Thread(target=CloudSearchThread,
args=(2, key_set, window, 0)).start()
# print(time.strftime("[%Y-%m-%d %H:%M:%S]: ", time.localtime()), "开启第2线程!\r")
threading.Thread(target=CloudSearchThread,
args=(3, key_set, window, 0)).start()
# print(time.strftime("[%Y-%m-%d %H:%M:%S]: ", time.localtime()), "开启第3线程!\r")
# 以下为第一版解决方案,单线程搜素
# cnt = 1
# starttime = time.time()
# for k in key_set:
# print(time.strftime("[%Y-%m-%d %H:%M:%S]: ", time.localtime()),
# '正在展示第 %d / %d 张: %s ...' % (cnt, len(key_set), k.split('/')[-1]))
# try:
# while True:
# try:
# r = requests.get(k, timeout=15)
# # if r.status_codes == 200:
# break
# except:
# print(time.strftime(
# "[%Y-%m-%d %H:%M:%S]: ", time.localtime()), 'IP被COS禁了,睡眠0.5分钟!')
# sleep(20)
# image = Image.open(BytesIO(r.content))
# image = image.resize((250, 250))
# buffered = BytesIO()
# image.save(buffered, format="PNG")
# img_str = base64.b64encode(buffered.getvalue())
# except:
# print(time.strftime(
# "[%Y-%m-%d %H:%M:%S]: ", time.localtime()), '由于某些原因,%s 已从网络端删除或者获取不到...' % (k))
# cnt += 1
# continue
# if cnt != 301:
# window['-IMG%s-' % (str(cnt))].update(data=img_str)
# else:
# print(time.strftime("[%Y-%m-%d %H:%M:%S]: ",
# time.localtime()), "窗口只能展示300张,超出限制,剩下的等等吧...")
# break
# cnt += 1
# elapse = time.time() - starttime
# # print(time.strftime("[%Y-%m-%d %H:%M:%S]: ", time.localtime()),'一共耗时:%.3fs'%(elapse))
# print(time.strftime("[%Y-%m-%d %H:%M:%S]: ", time.localtime()),
# "搜索结果展示完毕!实际展示了 %d 张表情包,展示搜索结果耗时:%.3fs" % (cnt - 1, elapse))
def CloudSearchThread(slice, key_set, window, random_flag):
global thread_cnt
global end_flag
global Search_starttime
if slice == 1:
slice_key_set = key_set[:len(key_set)//3]
elif slice == 2:
slice_key_set = key_set[len(key_set)//3: len(key_set)//3 * 2]
else:
slice_key_set = key_set[len(key_set)//3 * 2:]
img_cnt = slice
headers = {'Connection':'close'}
for k in slice_key_set:
# print(time.strftime("[%Y-%m-%d %H:%M:%S]: ", time.localtime()),'第%d线程搜索...正在展示第 %d / %d 张: %s ...\r' % (slice, thread_cnt, len(key_set), k.split('/')[-1]),end='')
try:
while True:
try:
r = requests.get(k, timeout=15,headers=headers)
# if r.status_codes == 200:
break
except:
print(time.strftime(
"\n[%Y-%m-%d %H:%M:%S]: ", time.localtime()), 'IP被COS禁了,睡眠0.5分钟!')
sleep(20)
image = Image.open(BytesIO(r.content))
image = image.resize((250, 250))
buffered = BytesIO()
image.save(buffered, format="PNG")
img_str = base64.b64encode(buffered.getvalue())
except:
print(time.strftime(
"\n[%Y-%m-%d %H:%M:%S]: ", time.localtime()), '由于某些原因,%s 已从网络端删除或者获取不到...' % (k))
thread_cnt += 1
img_cnt += 3
continue
if img_cnt <= 300:
window['-IMG%s-' % (str(img_cnt))].update(data=img_str)
else:
print(time.strftime("\n[%Y-%m-%d %H:%M:%S]: ",
time.localtime()), "窗口只能展示300张,超出限制,剩下的等等吧...")
break
thread_cnt += 1
img_cnt += 3
elapse = time.time() - Search_starttime
end_flag += 1
global breakFlag
if end_flag == 3 and random_flag == 0:
breakFlag = 0
print(time.strftime("\n[%Y-%m-%d %H:%M:%S]: ", time.localtime()),
"所有搜索线程结束,搜索结果展示完毕!实际展示了 %d 张表情包,展示搜索结果耗时:%.3fs" % (thread_cnt, elapse))
if end_flag == 3 and random_flag == 1:
breakFlag = 0
print(time.strftime("\n[%Y-%m-%d %H:%M:%S]: ", time.localtime()),
"随机6张表情包,送给亲爱的TA,展示搜索结果耗时:%.3fs" % (elapse))
def DownloadAndUpdate(path, window):
print(time.strftime("[%Y-%m-%d %H:%M:%S]: ",
time.localtime()), "开始下载更新!")
path = path + '/'
path = path.replace('/', '//')
pics = os.listdir(path)
Exist = []
if os.path.exists(path + 'history.txt'):
with open(path + 'history.txt', 'r+') as f:
lines = f.readlines()
for line in lines:
Exist.append(line.replace("\n", ""))
f.close()
while True:
try:
conn = pymysql.connect(
'47.96.189.80', user="root", passwd="189154", db="EmojiPic")
break
except:
print(time.strftime("[%Y-%m-%d %H:%M:%S]: ",
time.localtime()), '重连数据库中...')
try:
conn.close()
except:
pass
cur = conn.cursor()
cur.execute("SELECT * FROM EMOJITEXT;")
resTuple = cur.fetchall()
cur.close()
conn.close()
cnt = 0
num = 0
for res in resTuple:
if res[0].split('/')[-1] not in Exist:
num += 1
starttime = time.time()
if num == 0:
print(time.strftime("[%Y-%m-%d %H:%M:%S]: ",
time.localtime()), "已经与数据库同步,无需更新!")
return
for res in resTuple:
picurl = res[0]
picname = picurl.split('/')[-1]
if picname not in Exist:
print(time.strftime("[%Y-%m-%d %H:%M:%S]: ",
time.localtime()), "正在下载第 %d / %d 张:%s" % (cnt + 1, num, picname))
while True:
try:
r = requests.get(picurl, timeout=15)
# if r.status_codes == 200:
break
except:
print(time.strftime(
"[%Y-%m-%d %H:%M:%S]: ", time.localtime()), 'IP被COS禁了,睡眠0.5分钟!')
sleep(20)
with open(path + picname, "wb") as f:
f.write(r.content)
f.close()
cnt += 1
window['-DOWNLOADPROGRESS-'].update_bar(100/num * cnt)
window['-DOWNLOADPROGRESS_NUM-'].update(str(cnt/num * 100) + '%%')
with open(path + 'history.txt', 'a+') as f:
f.writelines(picname)
f.writelines('\n')
f.close()
else:
print(time.strftime("[%Y-%m-%d %H:%M:%S]: ", time.localtime()),
"正在下载第 %d / %d 张:%s 已经存在!" % (cnt + 1, num, picname))
# window['-DOWNLOADPROGRESS-'].update_bar(100/num * cnt)
# window['-DOWNLOADPROGRESS_NUM-'].update(str(cnt/num * 100) + '%%')
elapse = time.time() - starttime
print(time.strftime("[%Y-%m-%d %H:%M:%S]: ",
time.localtime()), "一共下载了 %d 张表情包,总耗时:%.3fs" % (cnt, elapse))
def LocalRecognition(path, window):
path = path + '/'
path = path.replace('/', '//')
pics = os.listdir(path)
server_url = ECS_url
server_headers = {"Content-type": "application/json"}
cnt = 0
total_time = 0
if not os.path.exists(path + 'result.csv'):
pd_data = pd.DataFrame([], columns=['name', 'text'])
pd_data.to_csv(path + 'result.csv', encoding='utf_8_sig')
img_end = {'jpg', 'bmp', 'png', 'jpeg', 'rgb', 'tif', 'tiff', 'gif', 'GIF'}
result = pd.read_csv(path + 'result.csv', encoding='utf_8_sig')
result_list = result['name'].to_list()
num = 0
print(time.strftime("[%Y-%m-%d %H:%M:%S]: ", time.localtime()),
"目录:“%s” 一共有 %d 个文件!" % (path, len(pics)))
try:
for p in pics:
if p not in result_list and p.split('.')[-1] in img_end:
num += 1
except:
pass
try:
pics = [pic for pic in pics if pic.split('.')[-1] in img_end]
except:
print(time.strftime("[%Y-%m-%d %H:%M:%S]: ",
time.localtime()), "目录:%s 含有没有后缀的文件,直接过滤掉!" % (path))
pics = [pic for pic in pics if '.' in pic]
pics = [pic for pic in pics if pic.split('.')[-1] in img_end]
print(time.strftime("[%Y-%m-%d %H:%M:%S]: ",
time.localtime()), "过滤掉非图片文件后,一共有 %d 个图片!" % (len(pics)))
print(time.strftime("[%Y-%m-%d %H:%M:%S]: ",
time.localtime()), "此目录还未识别的表情包一共有:%d 张!" % (num))
for p in pics:
if os.path.isfile(path + p):
if p not in result_list:
img = open(path + p, 'rb').read()
starttime = time.time()
data = {'images': [cv2_to_base64(img)]}
try:
r = requests.post(
url=server_url, headers=server_headers, data=json.dumps(data), timeout=30)
except:
print(time.strftime("[%Y-%m-%d %H:%M:%S]: ", time.localtime()),
"第 %d / %d 个识别项目:%s 识别时,服务器长时间未响应!" % (cnt+1, num, p))
continue
elapse = time.time() - starttime
total_time += elapse
print(time.strftime(
"[%Y-%m-%d %H:%M:%S]: ", time.localtime()), "第 %d / %d 个识别项目: %s, 识别时间 %.3fs" % (cnt+1, num, p, elapse))
try:
res = r.json()["results"][0]
except:
print(time.strftime(
"[%Y-%m-%d %H:%M:%S]: ", time.localtime()), '识别项目:%s 无结果' % (p))
cnt += 1
continue
text = ''
for i in res:
text = text + i['text']
new = pd.DataFrame({'name': p, 'text': text}, index=[1])
result = result.append(new, ignore_index=True, sort=True)
cnt += 1
window['-RECPROGRESS_2-'].update_bar(100/num * (cnt))
window['-RECPROGRESS_NUM_2-'].update(
str((cnt) / num * 100) + "%%")
result.to_csv(path + 'result.csv', encoding='utf_8_sig')
try:
print(time.strftime("[%Y-%m-%d %H:%M:%S]: ", time.localtime()),
"平均识别时间: {}s".format(float(total_time) / cnt))
print(time.strftime("[%Y-%m-%d %H:%M:%S]: ", time.localtime()),
"总共识别时间: {}s".format(float(total_time)))
except:
pass
print(time.strftime("[%Y-%m-%d %H:%M:%S]: ",
time.localtime()), "总共识别了 %d 张表情包." % (cnt))
def LocalSearch(path, window, key):
for i in range(300):
window['-IMG%s-' % (str(i+1))].update(data=None)
path = path + '/'
path = path.replace('/', '//')
try:
result = pd.read_csv(path + 'result.csv', encoding='utf_8_sig')
except:
print(time.strftime("[%Y-%m-%d %H:%M:%S]: ", time.localtime()),
"请先识别!")
return
result = result.fillna('0')
result_list = result['name'].to_list()
if ',' in key or ',' in key: # 只要包含其中一个
try:
key_list = key.split(',')
except:
key_list = key.split(',')
key_set = set()
for k in key_list:
res_pic_name_list = [result.iloc[result[result.text == i].index.to_list(
)[0]]['name'] for i in result['text'] if k in i]
for n in res_pic_name_list:
key_set.add(n)
elif ';' in key or ';' in key: # 全都包含
try:
key_list = key.split(';')
except:
key_list = key.split(';')
key_intersection = []
key_cnt = 0
for k in key_list:
res_pic_name_list = [result.iloc[result[result.text == i].index.to_list(
)[0]]['name'] for i in result['text'] if k in i]
if key_cnt == 0:
key_intersection = res_pic_name_list
else:
key_intersection = list(
set(key_intersection).intersection(res_pic_name_list))
key_cnt += 1
key_set = key_intersection
else:
key_set = [result.iloc[result[result.text == i].index.to_list()[0]]['name']
for i in result['text'] if key in i]
print(time.strftime("[%Y-%m-%d %H:%M:%S]: ", time.localtime()),
"关键字:'%s' 本地一共找到 %d 张表情包!" % (key, len(key_set)))
if len(key_set) == 0:
print(time.strftime("[%Y-%m-%d %H:%M:%S]: ",
time.localtime()), "赶紧更新库存吧,已经不够你秀的了!")
return
cnt = 1
starttime = time.time()
for k in key_set:
image = Image.open(path + k)
image = image.resize((250, 250))
buffered = BytesIO()
image.save(buffered, format="PNG")
img_str = base64.b64encode(buffered.getvalue())
if cnt != 301:
window['-IMG%s-' % (str(cnt))].update(data=img_str)
else:
print(time.strftime("[%Y-%m-%d %H:%M:%S]: ",
time.localtime()), "窗口只能展示300张,超出限制,剩下的等等吧...")
break
cnt += 1
elapse = time.time() - starttime
print(time.strftime("[%Y-%m-%d %H:%M:%S]: ", time.localtime()),
"实际展示了 %d 张表情包,展示搜索结果耗时:%.3fs" % (cnt-1, elapse))
def LocalRandomSearch(path, window):
for i in range(300):
window['-IMG%s-' % (str(i+1))].update(data=None)
path = path + '/'
path = path.replace('/', '//')
try:
result = pd.read_csv(path + 'result.csv', encoding='utf_8_sig')
except:
print(time.strftime("[%Y-%m-%d %H:%M:%S]: ",
time.localtime()), "请先识别!")
return
result = result.fillna('0')
result_list = result['name'].to_list()
cnt = 1
starttime = time.time()
try:
key_set = random.sample(result_list, 6)
except:
print(time.strftime("[%Y-%m-%d %H:%M:%S]: ", time.localtime()),
"不够6张图片哦~")
return
for k in key_set:
image = Image.open(path + k)
image = image.resize((250, 250))
buffered = BytesIO()
image.save(buffered, format="PNG")
img_str = base64.b64encode(buffered.getvalue())
if cnt != 301:
window['-IMG%s-' % (str(cnt))].update(data=img_str)
else:
print(time.strftime("[%Y-%m-%d %H:%M:%S]: ",
time.localtime()), "窗口只能展示300张,超出限制,剩下的等等吧...")
break
cnt += 1
elapse = time.time() - starttime
print(time.strftime("[%Y-%m-%d %H:%M:%S]: ", time.localtime()),
"本地随机6张表情包,送给亲爱的TA,展示搜索结果耗时:%.3fs" % (elapse))
def ZhihuSpider(path, url, window):
path = path + '/'
path = path.replace('/', '//')
user = User(None)
global zhihu_starttime
zhihu_starttime = time.time()
print(time.strftime("[%Y-%m-%d %H:%M:%S]: ",
time.localtime()), "正在启动爬取引擎...")
inputArg = url.split('\n')[-1]
if inputArg.isdigit():
user.currentBrowseAnswer.id = inputArg
answerURL = "https://www.zhihu.com/answer/" + inputArg
elif inputArg[:4] == "http":
user.currentBrowseAnswer.id = inputArg[::-