From a08f44054a4ff9b3c756973fd4095c1829bf300d Mon Sep 17 00:00:00 2001 From: "guorong.zheng" <360996299@qq.com> Date: Mon, 9 Sep 2024 10:39:13 +0800 Subject: [PATCH 1/4] chore:channel match --- Pipfile | 1 - Pipfile.lock | 117 +---------------------------------------------- utils/channel.py | 38 +++++---------- 3 files changed, 12 insertions(+), 144 deletions(-) diff --git a/Pipfile b/Pipfile index 390cd854b35..37e40c467e0 100644 --- a/Pipfile +++ b/Pipfile @@ -25,7 +25,6 @@ opencc-python-reimplemented = "*" fake-useragent = "*" gunicorn = "*" pillow = "*" -rapidfuzz = "*" [requires] python_version = "3.8" diff --git a/Pipfile.lock b/Pipfile.lock index 1c81aab63e9..ca1a037a8f7 100644 --- a/Pipfile.lock +++ b/Pipfile.lock @@ -1,7 +1,7 @@ { "_meta": { "hash": { - "sha256": "c3bc89d92fe791d812a886ef856fc8313e40d40344b3ab2ddf89953e715c8da4" + "sha256": "0c043b448071382259f37d3dfaec5bb50bd0bb93647b8e0b6750eb1eceeda673" }, "pipfile-spec": 6, "requires": { @@ -954,121 +954,6 @@ "markers": "sys_platform == 'win32'", "version": "==0.2.3" }, - "rapidfuzz": { - "hashes": [ - "sha256:03126f9a040ff21d2a110610bfd6b93b79377ce8b4121edcb791d61b7df6eec5", - "sha256:048d55d36c02c6685a2b2741688503c3d15149694506655b6169dcfd3b6c2585", - "sha256:057bb03f39e285047d7e9412e01ecf31bb2d42b9466a5409d715d587460dd59b", - "sha256:0b1c2d504eddf97bc0f2eba422c8915576dbf025062ceaca2d68aecd66324ad9", - "sha256:0d1415a732ee75e74a90af12020b77a0b396b36c60afae1bde3208a78cd2c9fc", - "sha256:0e9125377fa3d21a8abd4fbdbcf1c27be73e8b1850f0b61b5b711364bf3b59db", - "sha256:110b6294396bc0a447648627479c9320f095c2034c0537f687592e0f58622638", - "sha256:111a20a3c090cf244d9406e60500b6c34b2375ba3a5009e2b38fd806fe38e337", - "sha256:13d8675a1fa7e2b19650ca7ef9a6ec01391d4bb12ab9e0793e8eb024538b4a34", - "sha256:18669bb6cdf7d40738526d37e550df09ba065b5a7560f3d802287988b6cb63cf", - "sha256:19c64d8ddb2940b42a4567b23f1681af77f50a5ff6c9b8e85daba079c210716e", - "sha256:1dc516ac6d32027be2b0196bedf6d977ac26debd09ca182376322ad620460feb", - "sha256:1de91e7fd7f525e10ea79a6e62c559d1b0278ec097ad83d9da378b6fab65a265", - "sha256:1ee2086f490cb501d86b7e386c1eb4e3a0ccbb0c99067089efaa8c79012c8952", - "sha256:1ef6a1a8f0b12f8722f595f15c62950c9a02d5abc64742561299ffd49f6c6944", - "sha256:1f1a33e84056b7892c721d84475d3bde49a145126bc4c6efe0d6d0d59cb31c29", - "sha256:22589c0b8ccc6c391ce7f776c93a8c92c96ab8d34e1a19f1bd2b12a235332632", - "sha256:2379e0b2578ad3ac7004f223251550f08bca873ff76c169b09410ec562ad78d8", - "sha256:268f8e1ca50fc61c0736f3fe9d47891424adf62d96ed30196f30f4bd8216b41f", - "sha256:3171653212218a162540a3c8eb8ae7d3dcc8548540b69eaecaf3b47c14d89c90", - "sha256:32532af1d70c6ec02ea5ac7ee2766dfff7c8ae8c761abfe8da9e527314e634e8", - "sha256:3445a35c4c8d288f2b2011eb61bce1227c633ce85a3154e727170f37c0266bb2", - "sha256:3492c7a42b7fa9f0051d7fcce9893e95ed91c97c9ec7fb64346f3e070dd318ed", - "sha256:35d3044cb635ca6b1b2b7b67b3597bd19f34f1753b129eb6d2ae04cf98cd3945", - "sha256:364587827d7cbd41afa0782adc2d2d19e3f07d355b0750a02a8e33ad27a9c368", - "sha256:3665b92e788578c3bb334bd5b5fa7ee1a84bafd68be438e3110861d1578c63a0", - "sha256:36dd6e820379c37a1ffefc8a52b648758e867cd9d78ee5b5dc0c9a6a10145378", - "sha256:3ed5adb752f4308fcc8f4fb6f8eb7aa4082f9d12676fda0a74fa5564242a8107", - "sha256:47e92c155a14f44511ea8ebcc6bc1535a1fe8d0a7d67ad3cc47ba61606df7bcf", - "sha256:4ff196996240db7075f62c7bc4506f40a3c80cd4ae3ab0e79ac6892283a90859", - "sha256:521c58c72ed8a612b25cda378ff10dee17e6deb4ee99a070b723519a345527b9", - "sha256:5551d68264c1bb6943f542da83a4dc8940ede52c5847ef158698799cc28d14f5", - "sha256:578302828dd97ee2ba507d2f71d62164e28d2fc7bc73aad0d2d1d2afc021a5d5", - "sha256:579d107102c0725f7c79b4e79f16d3cf4d7c9208f29c66b064fa1fd4641d5155", - "sha256:591908240f4085e2ade5b685c6e8346e2ed44932cffeaac2fb32ddac95b55c7f", - "sha256:5a93c9e60904cb76e7aefef67afffb8b37c4894f81415ed513db090f29d01101", - "sha256:5d1eff95362f993b0276fd3839aee48625b09aac8938bb0c23b40d219cba5dc5", - "sha256:5d5262383634626eb45c536017204b8163a03bc43bda880cf1bdd7885db9a163", - "sha256:5f8bf3f0d02935751d8660abda6044821a861f6229f7d359f98bcdcc7e66c39b", - "sha256:603f48f621272a448ff58bb556feb4371252a02156593303391f5c3281dfaeac", - "sha256:675b75412a943bb83f1f53e2e54fd18c80ef15ed642dc6eb0382d1949419d904", - "sha256:68bd888eafd07b09585dcc8bc2716c5ecdb7eed62827470664d25588982b2873", - "sha256:696a79018ef989bf1c9abd9005841cee18005ccad4748bad8a4c274c47b6241a", - "sha256:6c5b32875646cb7f60c193ade99b2e4b124f19583492115293cd00f6fb198b17", - "sha256:6f83221db5755b8f34222e40607d87f1176a8d5d4dbda4a55a0f0b67d588a69c", - "sha256:6fb76e5a21034f0307c51c5a2fc08856f698c53a4c593b17d291f7d6e9d09ca3", - "sha256:7abe2dbae81120a64bb4f8d3fcafe9122f328c9f86d7f327f174187a5af4ed86", - "sha256:7b702de95666a1f7d5c6b47eacadfe2d2794af3742d63d2134767d13e5d1c713", - "sha256:7c20c1474b068c4bd45bf2fd0ad548df284f74e9a14a68b06746c56e3aa8eb70", - "sha256:836f4d88b8bd0fff2ebe815dcaab8aa6c8d07d1d566a7e21dd137cf6fe11ed5b", - "sha256:8501000a5eb8037c4b56857724797fe5a8b01853c363de91c8d0d0ad56bef319", - "sha256:8772b745668260c5c4d069c678bbaa68812e6c69830f3771eaad521af7bc17f8", - "sha256:8b01153c7466d0bad48fba77a303d5a768e66f24b763853469f47220b3de4661", - "sha256:8d92c552c6b7577402afdd547dcf5d31ea6c8ae31ad03f78226e055cfa37f3c6", - "sha256:9030e7238c0df51aed5c9c5ed8eee2bdd47a2ae788e562c1454af2851c3d1906", - "sha256:90db86fa196eecf96cb6db09f1083912ea945c50c57188039392d810d0b784e1", - "sha256:948dcee7aaa1cd14358b2a7ef08bf0be42bf89049c3a906669874a715fc2c937", - "sha256:94baaeea0b4f8632a6da69348b1e741043eba18d4e3088d674d3f76586b6223d", - "sha256:953b3780765c8846866faf891ee4290f6a41a6dacf4fbcd3926f78c9de412ca6", - "sha256:95b8292383e717e10455f2c917df45032b611141e43d1adf70f71b1566136b11", - "sha256:965693c2e9efd425b0f059f5be50ef830129f82892fa1858e220e424d9d0160f", - "sha256:97f2ce529d2a70a60c290f6ab269a2bbf1d3b47b9724dccc84339b85f7afb044", - "sha256:9b6a5de507b9be6de688dae40143b656f7a93b10995fb8bd90deb555e7875c60", - "sha256:9dba13d86806fcf3fe9c9919f58575e0090eadfb89c058bde02bcc7ab24e4548", - "sha256:9dc86aa6b29d174713c5f4caac35ffb7f232e3e649113e8d13812b35ab078228", - "sha256:9dcd14cf4876f04b488f6e54a7abd3e9b31db5f5a6aba0ce90659917aaa8c088", - "sha256:a3b36e1c61b796ae1777f3e9e11fd39898b09d351c9384baf6e3b7e6191d8ced", - "sha256:a3c0783910911f4f24655826d007c9f4360f08107410952c01ee3df98c713eb2", - "sha256:a40184c67db8252593ec518e17fb8a6e86d7259dc9f2d6c0bf4ff4db8cf1ad4b", - "sha256:a4da514d13f4433e16960a17f05b67e0af30ac771719c9a9fb877e5004f74477", - "sha256:a8feac9006d5c9758438906f093befffc4290de75663dbb2098461df7c7d28dd", - "sha256:a93cd834b3c315ab437f0565ee3a2f42dd33768dc885ccbabf9710b131cf70d2", - "sha256:ae1a38bade755aa9dd95a81cda949e1bf9cd92b79341ccc5e2189c9e7bdfc5ec", - "sha256:b23806fbdd6b510ba9ac93bb72d503066263b0fba44b71b835be9f063a84025f", - "sha256:b4f86e09d3064dca0b014cd48688964036a904a2d28048f00c8f4640796d06a8", - "sha256:b997ff3b39d4cee9fb025d6c46b0a24bd67595ce5a5b652a97fb3a9d60beb651", - "sha256:be3a1fc3e2ab3bdf93dc0c83c00acca8afd2a80602297d96cf4a0ba028333cdf", - "sha256:c12d180b17a22d107c8747de9c68d0b9c1d15dcda5445ff9bf9f4ccfb67c3e16", - "sha256:c1318d42610c26dcd68bd3279a1bf9e3605377260867c9a8ed22eafc1bd93a7c", - "sha256:c33211cfff9aec425bb1bfedaf94afcf337063aa273754f22779d6dadebef4c2", - "sha256:c4eebf6c93af0ae866c22b403a84747580bb5c10f0d7b51c82a87f25405d4dcb", - "sha256:c4f28f1930b09a2c300357d8465b388cecb7e8b2f454a5d5425561710b7fd07f", - "sha256:ca66676c8ef6557f9b81c5b2b519097817a7c776a6599b8d6fcc3e16edd216fe", - "sha256:ccf68e30b80e903f2309f90a438dbd640dd98e878eeb5ad361a288051ee5b75c", - "sha256:cd9360e30041690912525a210e48a897b49b230768cc8af1c702e5395690464f", - "sha256:cfa74aac64c85898b93d9c80bb935a96bf64985e28d4ee0f1a3d1f3bf11a5106", - "sha256:d098ce6162eb5e48fceb0745455bc950af059df6113eec83e916c129fca11408", - "sha256:d1230e0f9026851a6a432beaa0ce575dda7b39fe689b576f99a0704fbb81fc9c", - "sha256:d4ba2318ef670ce505f42881a5d2af70f948124646947341a3c6ccb33cd70369", - "sha256:d4e049d5ad61448c9a020d1061eba20944c4887d720c4069724beb6ea1692507", - "sha256:d73ee2df41224c87336448d279b5b6a3a75f36e41dd3dcf538c0c9cce36360d8", - "sha256:d7df9c2194c7ec930b33c991c55dbd0c10951bd25800c0b7a7b571994ebbced5", - "sha256:d95751f505a301af1aaf086c19f34536056d6c8efa91b2240de532a3db57b543", - "sha256:dd5fa6e3c6e0333051c1f3a49f0807b3366f4131c8d6ac8c3e05fd0d0ce3755c", - "sha256:df596ddd3db38aa513d4c0995611267b3946e7cbe5a8761b50e9306dfec720ee", - "sha256:e2957fdad10bb83b1982b02deb3604a3f6911a5e545f518b59c741086f92d152", - "sha256:e3dcfbe7266e74a707173a12a7b355a531f2dcfbdb32f09468e664330da14874", - "sha256:e6d9db2fa4e9be171e9bb31cf2d2575574774966b43f5b951062bb2e67885852", - "sha256:e9012d86c6397edbc9da4ac0132de7f8ee9d6ce857f4194d5684c4ddbcdd1c5c", - "sha256:e9fbf659537d246086d0297628b3795dc3e4a384101ecc01e5791c827b8d7345", - "sha256:ecc24af7f905f3d6efb371a01680116ffea8d64e266618fb9ad1602a9b4f7934", - "sha256:ece45eb2af8b00f90d10f7419322e8804bd42fb1129026f9bfe712c37508b514", - "sha256:f1c7296534c1afb6f495aa95871f14ccdc197c6db42965854e483100df313030", - "sha256:f847fb0fbfb72482b1c05c59cbb275c58a55b73708a7f77a83f8035ee3c86497", - "sha256:fbda3dd68d8b28ccb20ffb6f756fefd9b5ba570a772bedd7643ed441f5793308", - "sha256:fc3e6081069eea61593f1d6839029da53d00c8c9b205c5534853eaa3f031085c", - "sha256:fcf79b686962d7bec458a0babc904cb4fa319808805e036b9d5a531ee6b9b835", - "sha256:fde81b1da9a947f931711febe2e2bee694e891f6d3e6aa6bc02c1884702aea19" - ], - "index": "aliyun", - "markers": "python_version >= '3.8'", - "version": "==3.9.7" - }, "requests": { "hashes": [ "sha256:55365417734eb18255590a9ff9eb97e9e1da868d4ccd6402399eaf68af20a760", diff --git a/utils/channel.py b/utils/channel.py index ab2f04bb7f7..67c5f57b7a2 100644 --- a/utils/channel.py +++ b/utils/channel.py @@ -10,7 +10,6 @@ from opencc import OpenCC import asyncio import base64 -from rapidfuzz import process log_dir = "output" log_file = "result_new.log" @@ -118,17 +117,6 @@ def format_channel_name(name): return name.lower() -def get_channel_name_matches(query=None, choices=None, threshold=80): - """ - Get channel name matches with rapidfuzz - """ - query = format_channel_name(query) - matches = process.extract(query, choices, limit=len(choices)) - threshold = 100 if "cctv" in query else threshold - filtered_matches = [match[0] for match in matches if match[1] >= threshold] - return filtered_matches - - def channel_name_is_equal(name1, name2): """ Check if the channel name is equal @@ -137,23 +125,20 @@ def channel_name_is_equal(name1, name2): return True name1_format = format_channel_name(name1) name2_format = format_channel_name(name2) - matches = get_channel_name_matches(name1_format, [name2_format]) - return len(matches) > 0 + return name1_format == name2_format def get_channel_results_by_name(name, data): """ Get channel results from data by name """ + format_name = format_channel_name(name) cc = OpenCC("s2t") - name_s2t = cc.convert(name) - data_keys = data.keys() - name_matches_set = set( - get_channel_name_matches(name, data_keys) - + get_channel_name_matches(name_s2t, data_keys) - ) - result = [item for name_match in name_matches_set for item in data[name_match]] - return result + name_s2t = cc.convert(format_name) + result1 = data.get(format_name, []) + result2 = data.get(name_s2t, []) + results = list(dict.fromkeys(result1 + result2)) + return results def get_element_child_text_list(element, child_name): @@ -203,11 +188,10 @@ def get_channel_multicast_name_region_type_result(result, names): """ name_region_type_result = {} for name in names: - matches = get_channel_name_matches(name, result.keys()) - for match in matches: - data = result.get(match) - if data and match not in name_region_type_result: - name_region_type_result[match] = data + format_name = format_channel_name(name) + data = result.get(format_name) + if data: + name_region_type_result[format_name] = data return name_region_type_result From d744e69eba06f8e1dc1dfbc46ba1eec0455140cc Mon Sep 17 00:00:00 2001 From: "guorong.zheng" <360996299@qq.com> Date: Mon, 9 Sep 2024 11:00:39 +0800 Subject: [PATCH 2/4] fix:m3u channel name(#301) --- utils/tools.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/utils/tools.py b/utils/tools.py index 52d06854d30..fbea39f8e97 100644 --- a/utils/tools.py +++ b/utils/tools.py @@ -262,7 +262,10 @@ def convert_to_m3u(): str.strip, trimmed_line.split(",") ) processed_channel_name = re.sub( - r"(CCTV|CETV)-(\d+).*", r"\1\2", original_channel_name + r"(CCTV|CETV)-(\d+)(\+.*)?", + lambda m: f"{m.group(1)}{m.group(2)}" + + ("+" if m.group(3) else ""), + original_channel_name, ) m3u_output += f'#EXTINF:-1 tvg-name="{processed_channel_name}" tvg-logo="https://live.fanmingming.com/tv/{processed_channel_name}.png"' if current_group: From c3d0ef835cb44d3f43722e3cf2a3aa49a4ee158c Mon Sep 17 00:00:00 2001 From: "guorong.zheng" <360996299@qq.com> Date: Mon, 9 Sep 2024 18:05:22 +0800 Subject: [PATCH 3/4] feat:fofa tmp --- .github/workflows/main.yml | 6 ++ tkinter_ui/tkinter_ui.spec | 2 + updates/fofa/fofa_hotel_region_result.pkl | Bin 0 -> 211949 bytes updates/fofa/fofa_multicast_region_result.pkl | Bin 0 -> 252 bytes updates/fofa/request.py | 70 ++++++++++++++++-- 5 files changed, 71 insertions(+), 7 deletions(-) create mode 100644 updates/fofa/fofa_hotel_region_result.pkl create mode 100644 updates/fofa/fofa_multicast_region_result.pkl diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index eafa8c1f7fd..6fba53831b5 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -115,6 +115,12 @@ jobs: elif [[ -f "output/result.log" ]]; then git add -f "output/result.log" fi + if [[ -f "updates/fofa/fofa_hotel_region_result.pkl" ]]; then + git add -f "updates/fofa/fofa_hotel_region_result.pkl" + fi + if [[ -f "updates/fofa/fofa_multicast_region_result.pkl" ]]; then + git add -f "updates/fofa/fofa_multicast_region_result.pkl" + fi if ! git diff --staged --quiet; then git commit -m "Github Action Auto Updated" git push --force diff --git a/tkinter_ui/tkinter_ui.spec b/tkinter_ui/tkinter_ui.spec index 161d0f9bf1f..e03f8772418 100644 --- a/tkinter_ui/tkinter_ui.spec +++ b/tkinter_ui/tkinter_ui.spec @@ -10,6 +10,8 @@ a = Analysis( ('../config/rtp', 'config/rtp'), ('../updates/multicast/multicast_map.json', 'updates/multicast'), ('../updates/multicast/multicast_region_result.json', 'updates/multicast'), + ('../updates/fofa/fofa_hotel_region_result.pkl', 'updates/fofa'), + ('../updates/fofa/fofa_multicast_region_result.pkl', 'updates/fofa'), ('../static/images/favicon.ico', 'static/images'), ('../static/images/appreciate.jpg', 'static/images'), ('../static/images/settings_icon.png', 'static/images'), diff --git a/updates/fofa/fofa_hotel_region_result.pkl b/updates/fofa/fofa_hotel_region_result.pkl new file mode 100644 index 0000000000000000000000000000000000000000..338dd54f5156089fa5c351f59f3ce0f8d065e85d GIT binary patch literal 211949 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

GXSHrGT;bfQ`)SXwIa}wUHrUTr1gj=LL3Y-&up1 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 M)>bWj@%YUD2M>ARsQ>@~ literal 0 HcmV?d00001 diff --git a/updates/fofa/fofa_multicast_region_result.pkl b/updates/fofa/fofa_multicast_region_result.pkl new file mode 100644 index 0000000000000000000000000000000000000000..364626b8c1f4f8506fe4d8d6008712b308407206 GIT binary patch literal 252 zcmZo*nfj3d0&1u9uszw)^=#|*DLvfD`8heM$t9WjdBs3pN@`kSX--K>W^&1t$y0hb zl1ejkN-{xGEIFCQAhFgdK|t*<8mGK$m^CGKibjuQMoCG5mA<}_k%69}rIDVYk)Dx( lm4$(U@f1J5_9@upO^iVDh6Ln|2*~3$A7Vd5e`;~D9sn^|Q?md7 literal 0 HcmV?d00001 diff --git a/updates/fofa/request.py b/updates/fofa/request.py index 165fc502e1f..5aa4a079047 100644 --- a/updates/fofa/request.py +++ b/updates/fofa/request.py @@ -1,8 +1,8 @@ -from utils.config import config +from utils.config import config, resource_path from tqdm.asyncio import tqdm_asyncio from time import time from requests import get -from concurrent.futures import ThreadPoolExecutor +from concurrent.futures import ThreadPoolExecutor, as_completed import updates.fofa.fofa_map as fofa_map from driver.setup import setup_driver import re @@ -12,6 +12,8 @@ from updates.proxy import get_proxy, get_proxy_next from requests_custom.utils import get_source_requests, close_session from collections import defaultdict +import pickle +import threading timeout = 10 @@ -20,7 +22,11 @@ def get_fofa_urls_from_region_list(): """ Get the FOFA url from region """ - region_list = config.get("Settings", "hotel_region_list").split(",") + region_list = [ + region.strip() + for region in config.get("Settings", "hotel_region_list").split(",") + if region.strip() + ] urls = [] region_url = getattr(fofa_map, "region_url") if "all" in region_list or "ALL" in region_list or "全部" in region_list: @@ -32,6 +38,30 @@ def get_fofa_urls_from_region_list(): return urls +def update_fofa_region_result_tmp(result, multicast=False): + """ + Update fofa region result tmp + """ + with open( + resource_path( + f"updates/fofa/fofa_{'multicast' if multicast else 'hotel'}_region_result.pkl" + ), + "wb", + ) as file: + pickle.dump(result, file) + + +def get_fofa_region_result_tmp(multicast: False): + with open( + resource_path( + f"updates/fofa/fofa_{'multicast' if multicast else 'hotel'}_region_result.pkl" + ), + "rb", + ) as file: + result = pickle.load(file) + return result + + async def get_channels_by_fofa(urls=None, multicast=False, callback=None): """ Get the channel by FOFA @@ -57,9 +87,12 @@ async def get_channels_by_fofa(urls=None, multicast=False, callback=None): if open_proxy: test_url = fofa_urls[0][0] if multicast else fofa_urls[0] proxy = await get_proxy(test_url, best=True, with_test=True) + cancel_event = threading.Event() def process_fofa_channels(fofa_info): - nonlocal proxy, fofa_urls_len, open_driver, open_sort + nonlocal proxy, fofa_urls_len, open_driver, open_sort, cancel_event + if cancel_event.is_set(): + return {} fofa_url = fofa_info[0] if multicast else fofa_info results = defaultdict(lambda: defaultdict(list)) try: @@ -79,6 +112,9 @@ def process_fofa_channels(fofa_info): page_source = retry_func( lambda: get_source_requests(fofa_url), name=fofa_url ) + if "资源访问每天限制" in page_source: + cancel_event.set() + raise ValueError("Limited access to fofa page") fofa_source = re.sub(r"", "", page_source, flags=re.DOTALL) urls = set(re.findall(r"https?://[\w\.-]+:\d+", fofa_source)) if multicast: @@ -94,6 +130,9 @@ def process_fofa_channels(fofa_info): ] for future in futures: results = merge_objects(results, future.result()) + return results + except ValueError as e: + raise e except Exception as e: print(e) finally: @@ -107,15 +146,32 @@ def process_fofa_channels(fofa_info): f"正在获取Fofa{mode_name}源, 剩余{remain}个查询地址待获取, 预计剩余时间: {get_pbar_remaining(n=pbar.n, total=pbar.total, start_time=start_time)}", int((pbar.n / fofa_urls_len) * 100), ) - return results max_workers = 3 if open_driver else 10 with ThreadPoolExecutor(max_workers=max_workers) as executor: futures = [ executor.submit(process_fofa_channels, fofa_url) for fofa_url in fofa_urls ] - for future in futures: - fofa_results = merge_objects(fofa_results, future.result()) + try: + for future in as_completed(futures): + fofa_results = merge_objects(fofa_results, future.result()) + except ValueError as e: + if "Limited access to fofa page" in str(e): + for future in futures: + future.cancel() + fofa_results = {} + if fofa_results: + update_fofa_region_result_tmp(fofa_results, multicast=multicast) + else: + fofa_results = get_fofa_region_result_tmp(multicast=multicast) + print(fofa_results) + pbar.n = fofa_urls_len + pbar.update(0) + if callback: + callback( + f"正在获取Fofa{mode_name}源", + 100, + ) if not open_driver: close_session() pbar.close() From 3a7114c01a9823847fc66b201f29f60c9e4d2803 Mon Sep 17 00:00:00 2001 From: "guorong.zheng" <360996299@qq.com> Date: Mon, 9 Sep 2024 18:06:46 +0800 Subject: [PATCH 4/4] chore --- main.py | 6 +++++- tkinter_ui/hotel.py | 2 +- tkinter_ui/multicast.py | 2 +- tkinter_ui/select_combobox.py | 2 +- updates/hotel/request.py | 6 +++++- updates/multicast/update_tmp.py | 6 +++++- updates/subscribe/request.py | 2 +- utils/channel.py | 12 ++++++++++-- utils/tools.py | 7 ++++--- 9 files changed, 33 insertions(+), 12 deletions(-) diff --git a/main.py b/main.py index 646e267d440..9e05e8fa671 100644 --- a/main.py +++ b/main.py @@ -93,7 +93,11 @@ async def visit_page(self, channel_names=None): continue if config.getboolean("Settings", setting): if setting == "open_subscribe": - subscribe_urls = config.get("Settings", "subscribe_urls").split(",") + subscribe_urls = [ + url.strip() + for url in config.get("Settings", "subscribe_urls").split(",") + if url.strip() + ] task = asyncio.create_task( task_func(subscribe_urls, callback=self.update_progress) ) diff --git a/tkinter_ui/hotel.py b/tkinter_ui/hotel.py index d783ea35549..4f6d34bd0c7 100644 --- a/tkinter_ui/hotel.py +++ b/tkinter_ui/hotel.py @@ -71,7 +71,7 @@ def init_ui(self, root): self.region_list_label.pack(side=tk.LEFT, padx=4, pady=8) regions = ["全部"] + list(getattr(fofa_map, "region_url").keys()) region_selected_values = [ - value + value.strip() for value in config.get("Settings", "hotel_region_list").split(",") if value.strip() ] diff --git a/tkinter_ui/multicast.py b/tkinter_ui/multicast.py index 10c8921bc94..82d4d9f59cd 100644 --- a/tkinter_ui/multicast.py +++ b/tkinter_ui/multicast.py @@ -86,7 +86,7 @@ def init_ui(self, root): regions.remove("全部") regions.insert(0, "全部") region_selected_values = [ - value + value.strip() for value in config.get("Settings", "multicast_region_list").split(",") if value.strip() ] diff --git a/tkinter_ui/select_combobox.py b/tkinter_ui/select_combobox.py index 57f7928b00b..018dcc1666a 100644 --- a/tkinter_ui/select_combobox.py +++ b/tkinter_ui/select_combobox.py @@ -24,7 +24,7 @@ def on_select(self, event): def on_text_change(self, event): text_value = self.get().strip() - value_list = [value.strip() for value in text_value.split(",")] + value_list = [value.strip() for value in text_value.split(",") if value.strip()] self.selected_values = [ value for value in self.selected_values if value in value_list ] diff --git a/updates/hotel/request.py b/updates/hotel/request.py index a8974403a3c..523241f6b45 100644 --- a/updates/hotel/request.py +++ b/updates/hotel/request.py @@ -35,7 +35,11 @@ async def get_channels_by_hotel(callback=None): open_proxy = config.getboolean("Settings", "open_proxy") open_driver = config.getboolean("Settings", "open_driver") page_num = config.getint("Settings", "hotel_page_num") - region_list = config.get("Settings", "hotel_region_list").split(",") + region_list = [ + region.strip() + for region in config.get("Settings", "hotel_region_list").split(",") + if region.strip() + ] if "all" in region_list or "ALL" in region_list or "全部" in region_list: fofa_region_name_list = list(getattr(fofa_map, "region_url").keys()) region_list = fofa_region_name_list diff --git a/updates/multicast/update_tmp.py b/updates/multicast/update_tmp.py index 107013e7953..5e590f4a729 100644 --- a/updates/multicast/update_tmp.py +++ b/updates/multicast/update_tmp.py @@ -103,7 +103,11 @@ def get_multicast_region_result_by_rtp_txt(callback=None): Get multicast region result by rtp txt """ rtp_path = resource_path("config/rtp") - config_region_list = set(config.get("Settings", "multicast_region_list").split(",")) + config_region_list = set( + region.strip() + for region in config.get("Settings", "multicast_region_list").split(",") + if region.strip() + ) rtp_file_list = [ filename.rsplit(".", 1)[0] for filename in os.listdir(rtp_path) diff --git a/updates/subscribe/request.py b/updates/subscribe/request.py index 2e8d2a0742e..8cf40ad916b 100644 --- a/updates/subscribe/request.py +++ b/updates/subscribe/request.py @@ -27,7 +27,7 @@ async def get_channels_by_subscribe_urls( subscribe_results = {} pattern = r"^(.*?),(?!#genre#)(.*?)$" subscribe_urls = [ - url + url.strip() for url in config.get("Settings", "subscribe_urls").split(",") if url.strip() ] diff --git a/utils/channel.py b/utils/channel.py index 67c5f57b7a2..953d2e6cdb7 100644 --- a/utils/channel.py +++ b/utils/channel.py @@ -199,7 +199,11 @@ def get_channel_multicast_region_type_list(result): """ Get the channel multicast region type list from result """ - config_region_list = set(config.get("Settings", "multicast_region_list").split(",")) + config_region_list = set( + region.strip() + for region in config.get("Settings", "multicast_region_list").split(",") + if region.strip() + ) region_type_list = { (region, type) for region_type in result.values() @@ -662,7 +666,11 @@ def get_multicast_fofa_search_urls(): """ Get the fofa search urls for multicast """ - config_region_list = config.get("Settings", "multicast_region_list").split(",") + config_region_list = [ + region.strip() + for region in config.get("Settings", "multicast_region_list").split(",") + if region.strip() + ] rtp_file_names = [] for filename in os.listdir(resource_path("config/rtp")): if filename.endswith(".txt") and "_" in filename: diff --git a/utils/tools.py b/utils/tools.py index fbea39f8e97..cb322785035 100644 --- a/utils/tools.py +++ b/utils/tools.py @@ -159,9 +159,10 @@ def check_by_domain_blacklist(url): Check by domain blacklist """ domain_blacklist = [ - urlparse(domain).netloc if urlparse(domain).scheme else domain + (parsed_domain.netloc if parsed_domain.scheme else stripped_domain) for domain in config.get("Settings", "domain_blacklist").split(",") - if domain.strip() + if (stripped_domain := domain.strip()) + and (parsed_domain := urlparse(stripped_domain)) ] return urlparse(url).netloc not in domain_blacklist @@ -171,7 +172,7 @@ def check_by_url_keywords_blacklist(url): Check by URL blacklist keywords """ url_keywords_blacklist = [ - keyword + keyword.strip() for keyword in config.get("Settings", "url_keywords_blacklist").split(",") if keyword.strip() ]