|
@@ -1,302 +1,333 @@
|
|
|
-import ctypes
|
|
|
|
|
-import platform
|
|
|
|
|
-import subprocess
|
|
|
|
|
-import sys
|
|
|
|
|
|
|
+import datetime
|
|
|
|
|
+import json
|
|
|
import os
|
|
import os
|
|
|
|
|
+import random
|
|
|
|
|
+import sched
|
|
|
import threading
|
|
import threading
|
|
|
import time
|
|
import time
|
|
|
-from datetime import datetime
|
|
|
|
|
|
|
+import urllib
|
|
|
|
|
+import urllib.request
|
|
|
|
|
+from random import Random
|
|
|
|
|
+
|
|
|
|
|
+import requests
|
|
|
|
|
+import yaml
|
|
|
|
|
+
|
|
|
|
|
+from tools import loggerKit, redis_client
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+# 随机生成token
|
|
|
|
|
+def get_token():
|
|
|
|
|
+ length_r = 32
|
|
|
|
|
+ token = ''
|
|
|
|
|
+ chars = '01'
|
|
|
|
|
+ length = len(chars) - 1
|
|
|
|
|
+ random = Random()
|
|
|
|
|
+ for i in range(length_r):
|
|
|
|
|
+ token += chars[random.randint(0, length)]
|
|
|
|
|
+ return token
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+# 随机获取user_agent
|
|
|
|
|
+def get_random_browser():
|
|
|
|
|
+ user_agent = [
|
|
|
|
|
+ "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.190 Safari/537.36",
|
|
|
|
|
+ "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.88 Safari/537.36",
|
|
|
|
|
+ "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.75 Safari/537.36",
|
|
|
|
|
+ "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.121 Safari/537.36",
|
|
|
|
|
+ "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/84.0.4147.105 Safari/537.36",
|
|
|
|
|
+ "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.116 Safari/537.36",
|
|
|
|
|
+ "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/82.0.4085.133 Safari/537.36",
|
|
|
|
|
+ "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.138 Safari/537.36",
|
|
|
|
|
+ "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.163 Safari/537.36",
|
|
|
|
|
+ "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.130 Safari/537.36",
|
|
|
|
|
+ "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.108 Safari/537.36",
|
|
|
|
|
+ "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.120 Safari/537.36",
|
|
|
|
|
+ "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/76.0.3809.132 Safari/537.36",
|
|
|
|
|
+ "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.142 Safari/537.36",
|
|
|
|
|
+ "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.169 Safari/537.36",
|
|
|
|
|
+ "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.103 Safari/537.36",
|
|
|
|
|
+ "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.121 Safari/537.36",
|
|
|
|
|
+ "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36",
|
|
|
|
|
+ "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.102 Safari/537.36",
|
|
|
|
|
+ "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.100 Safari/537.36",
|
|
|
|
|
+ "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:86.0) Gecko/20100101 Firefox/86.0",
|
|
|
|
|
+ "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:85.0) Gecko/20100101 Firefox/85.0",
|
|
|
|
|
+ "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:84.0) Gecko/20100101 Firefox/84.0",
|
|
|
|
|
+ "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:83.0) Gecko/20100101 Firefox/83.0",
|
|
|
|
|
+ "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:82.0) Gecko/20100101 Firefox/82.0",
|
|
|
|
|
+ "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:81.0) Gecko/20100101 Firefox/81.0",
|
|
|
|
|
+ "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:80.0) Gecko/20100101 Firefox/80.0",
|
|
|
|
|
+ "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:79.0) Gecko/20100101 Firefox/79.0",
|
|
|
|
|
+ "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:78.0) Gecko/20100101 Firefox/78.0",
|
|
|
|
|
+ "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:77.0) Gecko/20100101 Firefox/77.0",
|
|
|
|
|
+ "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:76.0) Gecko/20100101 Firefox/76.0",
|
|
|
|
|
+ "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:75.0) Gecko/20100101 Firefox/75.0",
|
|
|
|
|
+ "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:74.0) Gecko/20100101 Firefox/74.0",
|
|
|
|
|
+ "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:73.0) Gecko/20100101 Firefox/73.0",
|
|
|
|
|
+ "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:72.0) Gecko/20100101 Firefox/72.0",
|
|
|
|
|
+ "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:71.0) Gecko/20100101 Firefox/71.0",
|
|
|
|
|
+ "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:70.0) Gecko/20100101 Firefox/70.0",
|
|
|
|
|
+ "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:69.0) Gecko/20100101 Firefox/69.0",
|
|
|
|
|
+ "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:68.0) Gecko/20100101 Firefox/68.0",
|
|
|
|
|
+ "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:67.0) Gecko/20100101 Firefox/67.0",
|
|
|
|
|
+ "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.190 Safari/537.36 Edg/88.0.705.81",
|
|
|
|
|
+ "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.88 Safari/537.36 Edg/87.0.664.66",
|
|
|
|
|
+ "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.75 Safari/537.36 Edg/86.0.622.69",
|
|
|
|
|
+ "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.121 Safari/537.36 Edg/85.0.564.63",
|
|
|
|
|
+ "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/84.0.4147.125 Safari/537.36 Edg/84.0.522.63",
|
|
|
|
|
+ "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.97 Safari/537.36 Edg/83.0.478.45",
|
|
|
|
|
+ "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/82.0.4086.0 Safari/537.36 Edg/82.0.459.1",
|
|
|
|
|
+ "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.138 Safari/537.36 Edg/81.0.416.72",
|
|
|
|
|
+ "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.163 Safari/537.36 Edg/80.0.361.62",
|
|
|
|
|
+ "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.88 Safari/537.36 Edg/79.0.309.71",
|
|
|
|
|
+ "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.108 Safari/537.36 Edg/78.0.276.19",
|
|
|
|
|
+ "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36 Edg/77.0.235.27",
|
|
|
|
|
+ "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/76.0.3809.132 Safari/537.36 Edg/76.0.182.6",
|
|
|
|
|
+ "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.100 Safari/537.36 Edg/75.0.139.20",
|
|
|
|
|
+ "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.169 Safari/537.36 Edg/74.1.96.24",
|
|
|
|
|
+ "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.103 Safari/537.36 Edg/73.0.139.7",
|
|
|
|
|
+ "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.121 Safari/537.36 Edg/72.0.130.14",
|
|
|
|
|
+ "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36 Edg/71.0.194.0",
|
|
|
|
|
+ "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.102 Safari/537.36 Edg/70.0.3538.102",
|
|
|
|
|
+ "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/14.0 Safari/605.1.15",
|
|
|
|
|
+ "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/13.1.2 Safari/605.1.15",
|
|
|
|
|
+ "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/12.1.2 Safari/605.1.15",
|
|
|
|
|
+ "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/11.1.2 Safari/605.1.15",
|
|
|
|
|
+ "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/10.1.2 Safari/605.1.15",
|
|
|
|
|
+ "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/9.1.2 Safari/605.1.15",
|
|
|
|
|
+ "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/8.1.2 Safari/605.1.15",
|
|
|
|
|
+ "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/7.1.2 Safari/605.1.15",
|
|
|
|
|
+ "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/6.1.2 Safari/605.1.15",
|
|
|
|
|
+ "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/5.1.2 Safari/605.1.15",
|
|
|
|
|
+ "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/4.1.2 Safari/605.1.15",
|
|
|
|
|
+ "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/3.1.2 Safari/605.1.15",
|
|
|
|
|
+ "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/2.1.2 Safari/605.1.15",
|
|
|
|
|
+ "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/1.1.2 Safari/605.1.15",
|
|
|
|
|
+ "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/0.1.2 Safari/605.1.15",
|
|
|
|
|
+ "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/99.1.2 Safari/605.1.15",
|
|
|
|
|
+ "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/98.1.2 Safari/605.1.15",
|
|
|
|
|
+ "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/97.1.2 Safari/605.1.15",
|
|
|
|
|
+ "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/96.1.2 Safari/605.1.15",
|
|
|
|
|
+ "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/95.1.2 Safari/605.1.15",
|
|
|
|
|
+ "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36"
|
|
|
|
|
+ ]
|
|
|
|
|
+
|
|
|
|
|
+ return random.choice(user_agent)
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+def get_proxy_ip(page, page_size):
|
|
|
|
|
+ response = requests.get(
|
|
|
|
|
+ f"https://proxy.webshare.io/api/v2/proxy/list/?mode=direct&page={page}&page_size={page_size}",
|
|
|
|
|
+ # headers={"Authorization": "Token pmdz7f3wdrwhwp88zwxmgtvn9dsusk0557vd16sp"}
|
|
|
|
|
+ headers={"Authorization": "Token 0pl6i8wbtukg4sdnf3b61wwzhi0h95pze47w5h3p"}
|
|
|
|
|
+ )
|
|
|
|
|
+
|
|
|
|
|
+ if response.status_code == 200:
|
|
|
|
|
+ content = json.loads(response.text)
|
|
|
|
|
+ # print(content["results"])
|
|
|
|
|
+ random_proxy = random.choice(content["results"])
|
|
|
|
|
+ print(random_proxy)
|
|
|
|
|
+ if random_proxy['valid']:
|
|
|
|
|
+ username = random_proxy['username']
|
|
|
|
|
+ password = random_proxy['password']
|
|
|
|
|
+ proxy_address_ip = random_proxy['proxy_address']
|
|
|
|
|
+ port = random_proxy['port']
|
|
|
|
|
+ # print(proxy_address_ip, port)
|
|
|
|
|
+ proxy = f'{username}:{password}@{proxy_address_ip}:{port}'
|
|
|
|
|
+
|
|
|
|
|
+ return proxy
|
|
|
|
|
+
|
|
|
|
|
+ else:
|
|
|
|
|
+ return None, None
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+"""
|
|
|
|
|
+每天预先半小时存储好(早上8点半定时执行)
|
|
|
|
|
+"""
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+def save_proxy_ip(page, page_size):
|
|
|
|
|
+ response = requests.get(
|
|
|
|
|
+ f"https://proxy.webshare.io/api/v2/proxy/list/?mode=direct&page={page}&page_size={page_size}",
|
|
|
|
|
+ headers={"Authorization": "Token 0pl6i8wbtukg4sdnf3b61wwzhi0h95pze47w5h3p"}
|
|
|
|
|
+ )
|
|
|
|
|
+
|
|
|
|
|
+ if response.status_code == 200:
|
|
|
|
|
+ data = json.loads(response.text)
|
|
|
|
|
+ # print(content['results'])
|
|
|
|
|
+ # total = page * page_size
|
|
|
|
|
+ print(f"代理总数:{data['count']}, 下一页:{data['next']}, 上一页:{data['previous']}")
|
|
|
|
|
+ i = page * page_size - 1
|
|
|
|
|
+ for r_proxy in data['results']:
|
|
|
|
|
+ if r_proxy['valid']:
|
|
|
|
|
+ username = r_proxy['username']
|
|
|
|
|
+ password = r_proxy['password']
|
|
|
|
|
+ proxy_address_ip = r_proxy['proxy_address']
|
|
|
|
|
+ port = r_proxy['port']
|
|
|
|
|
+ proxy = f'{username}:{password}@{proxy_address_ip}:{port}'
|
|
|
|
|
+
|
|
|
|
|
+ # 连接Redis并存储代理IP
|
|
|
|
|
+ redis_client.set(f'proxy_{str(i)}', proxy)
|
|
|
|
|
+ i = i - 1
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+def save_all_proxy_ip(page_size, total_page):
|
|
|
|
|
+ for t in range(1, total_page):
|
|
|
|
|
+ loggerKit.info(f't:{t}')
|
|
|
|
|
+
|
|
|
|
|
+ url = f"https://proxy.webshare.io/api/v2/proxy/list/?mode=direct&page={t}&page_size={page_size}"
|
|
|
|
|
+ headers = {
|
|
|
|
|
+ "Authorization": "Token 0pl6i8wbtukg4sdnf3b61wwzhi0h95pze47w5h3p"
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ # 添加country查询参数来获取新加坡的IP
|
|
|
|
|
+ parameters = {
|
|
|
|
|
+ "country": "SG"
|
|
|
|
|
+ }
|
|
|
|
|
+ response = requests.get(url, headers=headers, params=parameters)
|
|
|
|
|
+ if response.status_code == 200:
|
|
|
|
|
+ data = json.loads(response.text)
|
|
|
|
|
+ loggerKit.info(f"代理总数:{data['count']}, 下一页:{data['next']}, 上一页:{data['previous']}")
|
|
|
|
|
+ i = t * page_size - 1
|
|
|
|
|
+ for r_proxy in data['results']:
|
|
|
|
|
+ if r_proxy['valid']:
|
|
|
|
|
+ username = r_proxy['username']
|
|
|
|
|
+ password = r_proxy['password']
|
|
|
|
|
+ proxy_address_ip = r_proxy['proxy_address']
|
|
|
|
|
+ port = r_proxy['port']
|
|
|
|
|
+ proxy = f'{username}:{password}@{proxy_address_ip}:{port}'
|
|
|
|
|
+
|
|
|
|
|
+ # 连接Redis并存储代理IP
|
|
|
|
|
+ redis_client.set(f'proxy_{str(i)}', proxy)
|
|
|
|
|
+ i = i - 1
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+"""
|
|
|
|
|
+读取指定proxy_list文件
|
|
|
|
|
+"""
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+def save_all_proxy_ip_v2():
|
|
|
|
|
+ i = 0
|
|
|
|
|
+ with open('proxy_list.txt', 'r') as proxies:
|
|
|
|
|
+ lines = [line.strip() for line in proxies]
|
|
|
|
|
+ for single_proxy in lines:
|
|
|
|
|
+ print(f'proxy:{single_proxy}')
|
|
|
|
|
+ # 存入redis
|
|
|
|
|
+ redis_client.set(f'proxy_{str(i)}', single_proxy, 24 * 60 * 60)
|
|
|
|
|
+ i = i + 1
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+"""
|
|
|
|
|
+读取指定proxy_list文件
|
|
|
|
|
+"""
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+def save_all_proxy_ip_v3(proxy_file_path):
|
|
|
|
|
+ i = 0
|
|
|
|
|
+ with open(proxy_file_path, 'r') as proxies:
|
|
|
|
|
+ lines = [line.strip() for line in proxies]
|
|
|
|
|
+ for single_proxy in lines:
|
|
|
|
|
+ print(f'proxy:{single_proxy}')
|
|
|
|
|
+ # 存入redis
|
|
|
|
|
+ redis_client.set(f'proxy_{str(i)}', single_proxy, 24 * 60 * 60)
|
|
|
|
|
+ i = i + 1
|
|
|
|
|
|
|
|
-from PyQt5.QtCore import Qt, QUrl, QDateTime
|
|
|
|
|
-from PyQt5.QtWidgets import QApplication, QMainWindow, QLabel, QFileDialog, QMessageBox, QDateTimeEdit, QPushButton
|
|
|
|
|
-from PyQt5.QtGui import QDesktopServices
|
|
|
|
|
|
|
|
|
|
-from app import login_account, run_threading_order, run_daily_job, run_manual_job, cancel_manual_job, stop_order_job, \
|
|
|
|
|
- write_ticket_info
|
|
|
|
|
-from litter_helper import Ui_menu # 确保这个导入路径是正确的
|
|
|
|
|
-from tools.utils import save_all_proxy_ip_v3
|
|
|
|
|
|
|
+def get_proxy_poc():
|
|
|
|
|
+ response = requests.get(
|
|
|
|
|
+ "https://proxy.webshare.io/api/v2/proxy/list/?page=1&page_size=10",
|
|
|
|
|
+ headers={"Authorization": "Token 0pl6i8wbtukg4sdnf3b61wwzhi0h95pze47w5h3p"}
|
|
|
|
|
+ )
|
|
|
|
|
|
|
|
-import winreg
|
|
|
|
|
|
|
+ if response.status_code == 200:
|
|
|
|
|
+ data = json.loads(response.text)
|
|
|
|
|
+ print(f"{json.loads(data)}")
|
|
|
|
|
|
|
|
-from pathlib import Path
|
|
|
|
|
|
|
|
|
|
-# 定义 Redis 安装程序路径
|
|
|
|
|
-REDIS_INSTALLER_PATH = "Redis-x64-5.0.14.1.msi" # 替换为实际的安装程序路径
|
|
|
|
|
|
|
+def get_random_proxy_at_redis(total):
|
|
|
|
|
+ random_index = random.randint(0, total - 1)
|
|
|
|
|
+ # 连接Redis并获取代理IP
|
|
|
|
|
+ single_proxy = redis_client.get(f'proxy_{str(random_index)}')
|
|
|
|
|
+
|
|
|
|
|
+ return single_proxy, random_index
|
|
|
|
|
|
|
|
|
|
|
|
|
-class ClickableLabel(QLabel):
|
|
|
|
|
- def __init__(self, parent=None, file_path=None):
|
|
|
|
|
- super().__init__(parent)
|
|
|
|
|
|
|
+def process_account(account_number):
|
|
|
|
|
+ print(f"Processing account {account_number}")
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+def task_running(num_account):
|
|
|
|
|
+ threads = []
|
|
|
|
|
+ for account_number in range(num_account):
|
|
|
|
|
+ thread = threading.Thread(target=process_account, args=(account_number,))
|
|
|
|
|
+ threads.append(thread)
|
|
|
|
|
+ thread.start()
|
|
|
|
|
+
|
|
|
|
|
+ for thread in threads:
|
|
|
|
|
+ thread.join()
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+class Singleton(type):
|
|
|
|
|
+ _instances = {}
|
|
|
|
|
+
|
|
|
|
|
+ def __call__(cls, *args, **kwargs):
|
|
|
|
|
+ if cls not in cls._instances:
|
|
|
|
|
+ cls._instances[cls] = super(Singleton, cls).__call__(*args, **kwargs)
|
|
|
|
|
+ return cls._instances[cls]
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+class FileWriter(metaclass=Singleton):
|
|
|
|
|
+
|
|
|
|
|
+ def __init__(self, file_path):
|
|
|
|
|
+ if not isinstance(file_path, str):
|
|
|
|
|
+ raise TypeError("file_path should be a string")
|
|
|
self.file_path = file_path
|
|
self.file_path = file_path
|
|
|
|
|
+ if not os.path.exists(self.file_path):
|
|
|
|
|
+ with open(self.file_path, 'a') as f:
|
|
|
|
|
+ print(f'File {self.file_path} created successfully!')
|
|
|
|
|
|
|
|
- def mousePressEvent(self, event):
|
|
|
|
|
- if event.button() == Qt.LeftButton:
|
|
|
|
|
- self.emit_click_event()
|
|
|
|
|
-
|
|
|
|
|
- def emit_click_event(self):
|
|
|
|
|
- if self.file_path:
|
|
|
|
|
- self.parent().on_label_click(self.file_path)
|
|
|
|
|
-
|
|
|
|
|
-
|
|
|
|
|
-def get_resource_path(relative_path):
|
|
|
|
|
- """获取资源文件的绝对路径"""
|
|
|
|
|
- if getattr(sys, 'frozen', False): # 是否为PyInstaller打包的exe文件
|
|
|
|
|
- # 返回exe文件所在的绝对路径
|
|
|
|
|
- base_path = os.path.dirname(sys.executable)
|
|
|
|
|
- else: # 在开发环境下运行
|
|
|
|
|
- # 返回脚本文件所在的绝对路径
|
|
|
|
|
- base_path = os.path.dirname(__file__)
|
|
|
|
|
- return os.path.join(base_path, relative_path)
|
|
|
|
|
-
|
|
|
|
|
-
|
|
|
|
|
-def get_dir_path(relative_path):
|
|
|
|
|
- """获取资源文件路径"""
|
|
|
|
|
- base_path = getattr(sys, '_MEIPASS', str(Path(__file__).parent.absolute()))
|
|
|
|
|
- return Path(base_path, relative_path)
|
|
|
|
|
-
|
|
|
|
|
-
|
|
|
|
|
-# 停止定时任务
|
|
|
|
|
-def on_stop_time_button_click():
|
|
|
|
|
- print(f"停止定时任务: {time.time()}")
|
|
|
|
|
- cancel_manual_job()
|
|
|
|
|
-
|
|
|
|
|
-
|
|
|
|
|
-# 写入文件
|
|
|
|
|
-def on_write_file_button_click():
|
|
|
|
|
- print(f"写入文件:{time.time()}")
|
|
|
|
|
- write_ticket_info("abcd", "1234556")
|
|
|
|
|
-
|
|
|
|
|
-
|
|
|
|
|
-class MainWindow(QMainWindow, Ui_menu):
|
|
|
|
|
- def __init__(self, param1, param2):
|
|
|
|
|
- super().__init__()
|
|
|
|
|
- self.setupUi(self)
|
|
|
|
|
-
|
|
|
|
|
- # 使用传递的参数
|
|
|
|
|
- self.param1 = param1
|
|
|
|
|
- self.param2 = param2
|
|
|
|
|
-
|
|
|
|
|
- # 设置标签的文本为传递的参数
|
|
|
|
|
- # self.label.setText(f"参数1: {self.param1}, 参数2: {self.param2}")
|
|
|
|
|
- self.concurrencyLineEdit.setText("1")
|
|
|
|
|
- self.urlLineEdit.setText("https://t.livepocket.jp/e/l3im7")
|
|
|
|
|
-
|
|
|
|
|
- # 登录账号
|
|
|
|
|
- self.loginPushButton.clicked.connect(self.on_login_button_click)
|
|
|
|
|
-
|
|
|
|
|
- # 开始下单
|
|
|
|
|
- self.startPushButton.clicked.connect(self.on_start_button_click)
|
|
|
|
|
-
|
|
|
|
|
- # 停止下单
|
|
|
|
|
- self.stopOrderPushButton.clicked.connect(self.on_stop_button_click)
|
|
|
|
|
-
|
|
|
|
|
- # 定时开始
|
|
|
|
|
- self.startTimePushButton.clicked.connect(self.on_start_time_button_click)
|
|
|
|
|
-
|
|
|
|
|
- # 停止定时任务
|
|
|
|
|
- self.stopTimePushButton.clicked.connect(on_stop_time_button_click)
|
|
|
|
|
-
|
|
|
|
|
- # 写入文件
|
|
|
|
|
- # self.writeFilePushButton.clicked.connect(on_write_file_button_click)
|
|
|
|
|
-
|
|
|
|
|
- # 编辑账号
|
|
|
|
|
- # 获取 QLabel 控件并替换为 ClickableLabel
|
|
|
|
|
- self.accountsLabel = self.findChild(QLabel, "accountsLabel")
|
|
|
|
|
- if self.accountsLabel:
|
|
|
|
|
- # 替换为 ClickableLabel
|
|
|
|
|
- self.clickableAccountsLabel = ClickableLabel(self, file_path=get_resource_path("accounts.txt"))
|
|
|
|
|
- self.clickableAccountsLabel.setObjectName("accountsLabel")
|
|
|
|
|
- self.clickableAccountsLabel.setText("编辑账号")
|
|
|
|
|
- self.clickableAccountsLabel.setGeometry(self.accountsLabel.geometry())
|
|
|
|
|
- self.clickableAccountsLabel.show()
|
|
|
|
|
- self.accountsLabel.deleteLater() # 删除原来的 QLabel 控件
|
|
|
|
|
-
|
|
|
|
|
- # 编辑IP代理池
|
|
|
|
|
- # 获取 QLabel 控件并替换为 ClickableLabel
|
|
|
|
|
- self.ipPoolLabel = self.findChild(QLabel, "ipPoolLabel")
|
|
|
|
|
- if self.ipPoolLabel:
|
|
|
|
|
- # 替换为 ClickableLabel
|
|
|
|
|
- self.clickableIpPoolLabel = ClickableLabel(self, file_path=get_resource_path("proxy_list.txt"))
|
|
|
|
|
- self.clickableIpPoolLabel.setObjectName("ipPoolLabel")
|
|
|
|
|
- self.clickableIpPoolLabel.setText("编辑代理池")
|
|
|
|
|
- self.clickableIpPoolLabel.setGeometry(self.ipPoolLabel.geometry())
|
|
|
|
|
- self.clickableIpPoolLabel.show()
|
|
|
|
|
- self.ipPoolLabel.deleteLater() # 删除原来的 QLabel 控件
|
|
|
|
|
-
|
|
|
|
|
- # 获取 QDateTimeEdit 控件并设置显示格式
|
|
|
|
|
- self.startDateTimeEdit = self.findChild(QDateTimeEdit, "startDateTimeEdit")
|
|
|
|
|
- if self.startDateTimeEdit:
|
|
|
|
|
- self.startDateTimeEdit.setDisplayFormat("yyyy-MM-dd HH:mm:ss")
|
|
|
|
|
- # 设置当前时间
|
|
|
|
|
- self.startDateTimeEdit.setDateTime(QDateTime.currentDateTime())
|
|
|
|
|
-
|
|
|
|
|
- # 获取 QDateTimeEdit 控件并设置显示格式
|
|
|
|
|
- self.endDateTimeEdit = self.findChild(QDateTimeEdit, "endDateTimeEdit")
|
|
|
|
|
- if self.endDateTimeEdit:
|
|
|
|
|
- self.endDateTimeEdit.setDisplayFormat("yyyy-MM-dd HH:mm:ss")
|
|
|
|
|
- # 设置当前时间
|
|
|
|
|
- self.endDateTimeEdit.setDateTime(QDateTime.currentDateTime())
|
|
|
|
|
-
|
|
|
|
|
- # 连接 watchPushButton 点击事件到槽函数
|
|
|
|
|
- self.watchPushButton = self.findChild(QPushButton, "watchPushButton")
|
|
|
|
|
- if self.watchPushButton:
|
|
|
|
|
- self.watchPushButton.clicked.connect(self.on_watch_button_click)
|
|
|
|
|
-
|
|
|
|
|
- # 检查 Redis 是否安装
|
|
|
|
|
- self.check_redis_installation()
|
|
|
|
|
-
|
|
|
|
|
- def on_label_click(self, file_path):
|
|
|
|
|
- if os.path.exists(file_path):
|
|
|
|
|
- try:
|
|
|
|
|
- QDesktopServices.openUrl(QUrl.fromLocalFile(file_path))
|
|
|
|
|
- except Exception as e:
|
|
|
|
|
- QMessageBox.critical(self, "Error", f"无法打开文件: {e}")
|
|
|
|
|
- else:
|
|
|
|
|
- QMessageBox.critical(self, "Error", f"文件不存在: {file_path}")
|
|
|
|
|
-
|
|
|
|
|
- def on_start_button_click(self):
|
|
|
|
|
- print(f"开始下单!")
|
|
|
|
|
- # 在按钮点击时执行的操作
|
|
|
|
|
- # print(f"按钮被点击了!参数1: {self.param1}, 参数2: {self.param2}")
|
|
|
|
|
-
|
|
|
|
|
- # 获取 QDateTimeEdit 控件的值
|
|
|
|
|
- if self.startDateTimeEdit:
|
|
|
|
|
- date_time_value = self.startDateTimeEdit.dateTime()
|
|
|
|
|
- # print(f"选中的日期和时间: {date_time_value.toString('yyyy-MM-dd HH:mm:ss')}")
|
|
|
|
|
-
|
|
|
|
|
- # 获取 QDateTimeEdit 控件的值
|
|
|
|
|
- if self.endDateTimeEdit:
|
|
|
|
|
- date_time_value = self.endDateTimeEdit.dateTime()
|
|
|
|
|
- # print(f"选中的日期和时间: {date_time_value.toString('yyyy-MM-dd HH:mm:ss')}")
|
|
|
|
|
-
|
|
|
|
|
- # 获取并发数
|
|
|
|
|
- thread_num = 1
|
|
|
|
|
- if self.concurrencyLineEdit:
|
|
|
|
|
- # print(f"并发数为: {self.concurrencyLineEdit.text()}")
|
|
|
|
|
- thread_num = self.concurrencyLineEdit.text()
|
|
|
|
|
-
|
|
|
|
|
- # url
|
|
|
|
|
- net_url = None
|
|
|
|
|
- if self.urlLineEdit:
|
|
|
|
|
- net_url = self.urlLineEdit.text()
|
|
|
|
|
-
|
|
|
|
|
- # 下单
|
|
|
|
|
- run_threading_order(thread_num, get_resource_path("accounts.txt"), net_url)
|
|
|
|
|
-
|
|
|
|
|
- # 登录账号
|
|
|
|
|
- def on_login_button_click(self):
|
|
|
|
|
- print(f"登录账号! {self.urlLineEdit.text()}")
|
|
|
|
|
-
|
|
|
|
|
- thread_num = 1
|
|
|
|
|
- if self.concurrencyLineEdit.text():
|
|
|
|
|
- thread_num = self.concurrencyLineEdit.text()
|
|
|
|
|
-
|
|
|
|
|
- pocket_url = None
|
|
|
|
|
- if self.urlLineEdit.text():
|
|
|
|
|
- pocket_url = self.urlLineEdit.text()
|
|
|
|
|
- save_all_proxy_ip_v3(get_resource_path("proxy_list.txt"))
|
|
|
|
|
- login_account(thread_num, get_resource_path("accounts.txt"), pocket_url)
|
|
|
|
|
- else:
|
|
|
|
|
- QMessageBox.warning(self, '警告', '请输入URL')
|
|
|
|
|
- return
|
|
|
|
|
-
|
|
|
|
|
- # 定时开始
|
|
|
|
|
- def on_start_time_button_click(self):
|
|
|
|
|
- print(f"定时开始:{time.time()}")
|
|
|
|
|
-
|
|
|
|
|
- net_url = None
|
|
|
|
|
- if self.urlLineEdit:
|
|
|
|
|
- net_url = self.urlLineEdit.text()
|
|
|
|
|
-
|
|
|
|
|
- start_time = self.startDateTimeEdit.text()
|
|
|
|
|
- print(f"start_time:{start_time}")
|
|
|
|
|
-
|
|
|
|
|
- # 使用datetime模块解析时间字符串
|
|
|
|
|
- dt = datetime.strptime(start_time, '%Y-%m-%d %H:%M:%S')
|
|
|
|
|
-
|
|
|
|
|
- # 提取出时、分、秒
|
|
|
|
|
- hour = dt.hour
|
|
|
|
|
- minute = dt.minute
|
|
|
|
|
- second = dt.second
|
|
|
|
|
-
|
|
|
|
|
- print(f"Hour: {hour}, Minute: {minute}, Second: {second}")
|
|
|
|
|
-
|
|
|
|
|
- # 获取并发数
|
|
|
|
|
- thread_num = self.concurrencyLineEdit.text()
|
|
|
|
|
-
|
|
|
|
|
- # 创建一个新的线程来运行 run_manual_job 函数
|
|
|
|
|
- thread = threading.Thread(target=run_manual_job, args=(hour, minute, thread_num, net_url))
|
|
|
|
|
- thread.start()
|
|
|
|
|
- else:
|
|
|
|
|
- QMessageBox.warning(self, '警告', '请输入URL')
|
|
|
|
|
- return
|
|
|
|
|
-
|
|
|
|
|
- # 终止下单
|
|
|
|
|
- def on_stop_button_click(self):
|
|
|
|
|
- print(f"终止下单! 目标网址: {self.urlLineEdit.text()}")
|
|
|
|
|
- stop_order_job()
|
|
|
|
|
-
|
|
|
|
|
- def edit_accounts(self):
|
|
|
|
|
- # 编辑账号
|
|
|
|
|
- print(f"编辑账号: {self.urlLineEdit.text()}")
|
|
|
|
|
-
|
|
|
|
|
- # 查看结果
|
|
|
|
|
- def on_watch_button_click(self):
|
|
|
|
|
- # 获取项目当前路径
|
|
|
|
|
- current_path = sys.path[0]
|
|
|
|
|
- # 拼接文件夹路径
|
|
|
|
|
- folder_path = get_dir_path("results") # 假设文件夹名为 "results"
|
|
|
|
|
-
|
|
|
|
|
- # 判断文件夹是否存在,不存在则创建
|
|
|
|
|
- if not folder_path.exists():
|
|
|
|
|
- try:
|
|
|
|
|
- folder_path.mkdir(parents=True, exist_ok=True)
|
|
|
|
|
- print(f"文件夹 {folder_path} 已创建")
|
|
|
|
|
- except Exception as e:
|
|
|
|
|
- QMessageBox.critical(self, "Error", f"无法创建文件夹: {e}")
|
|
|
|
|
- return
|
|
|
|
|
-
|
|
|
|
|
- # 打开文件夹
|
|
|
|
|
- folder_path = get_resource_path("results") # 假设文件夹名为 "results"
|
|
|
|
|
|
|
+ def write_to_file(self, content):
|
|
|
try:
|
|
try:
|
|
|
- # 使用 QDesktopServices.openUrl 打开文件夹
|
|
|
|
|
- QDesktopServices.openUrl(QUrl.fromLocalFile(folder_path))
|
|
|
|
|
|
|
+ with open(self.file_path, 'a') as file:
|
|
|
|
|
+ file.write(content)
|
|
|
except Exception as e:
|
|
except Exception as e:
|
|
|
- QMessageBox.critical(self, "Error", f"无法打开文件夹: {e}")
|
|
|
|
|
-
|
|
|
|
|
- # 检查 Redis 是否安装
|
|
|
|
|
- def check_redis_installation(self):
|
|
|
|
|
- # 检查操作系统
|
|
|
|
|
- system = platform.system()
|
|
|
|
|
-
|
|
|
|
|
- if system == "Windows":
|
|
|
|
|
- # 检查 Redis 服务是否正在运行
|
|
|
|
|
- try:
|
|
|
|
|
- key = winreg.OpenKey(winreg.HKEY_LOCAL_MACHINE, r"SYSTEM\CurrentControlSet\Services\Redis")
|
|
|
|
|
- winreg.CloseKey(key)
|
|
|
|
|
- print("Redis 服务已安装并正在运行")
|
|
|
|
|
- return
|
|
|
|
|
- except FileNotFoundError as ex:
|
|
|
|
|
- print(f"Redis 服务未安装或未运行")
|
|
|
|
|
-
|
|
|
|
|
- # 如果 Redis 服务未安装,则启动安装程序
|
|
|
|
|
- if REDIS_INSTALLER_PATH:
|
|
|
|
|
- try:
|
|
|
|
|
- subprocess.run([REDIS_INSTALLER_PATH], shell=True)
|
|
|
|
|
- print("Redis 安装程序已启动")
|
|
|
|
|
- except Exception as e:
|
|
|
|
|
- QMessageBox.critical(self, "Error", f"无法启动 Redis 安装程序: {e}")
|
|
|
|
|
- else:
|
|
|
|
|
- # 在其他操作系统上,可以使用不同的方法检查 Redis 是否安装
|
|
|
|
|
- # 例如,可以使用 `which redis-server` 命令
|
|
|
|
|
- print("当前操作系统不支持自动安装 Redis")
|
|
|
|
|
-
|
|
|
|
|
-
|
|
|
|
|
-if __name__ == "__main__":
|
|
|
|
|
- app = QApplication(sys.argv)
|
|
|
|
|
-
|
|
|
|
|
- # 创建窗口并传递参数
|
|
|
|
|
- window = MainWindow("Hello", "World")
|
|
|
|
|
- window.show()
|
|
|
|
|
-
|
|
|
|
|
- sys.exit(app.exec_())
|
|
|
|
|
|
|
+ print(f"An error occurred: {e}")
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+def run_daily_task(hour, minute, page_size, total):
|
|
|
|
|
+ # 获取当前日期和时间
|
|
|
|
|
+ now = datetime.datetime.now()
|
|
|
|
|
+ # 计算下次运行时间
|
|
|
|
|
+ run_time = datetime.datetime(now.year, now.month, now.day, hour, minute)
|
|
|
|
|
+ if run_time < now:
|
|
|
|
|
+ # 如果运行时间小于当前时间,则在明天的相应时间运行任务
|
|
|
|
|
+ run_time = run_time + datetime.timedelta(days=1)
|
|
|
|
|
+ # 计算等待时间
|
|
|
|
|
+ wait_time = (run_time - now).total_seconds()
|
|
|
|
|
+ # 创建定时器对象
|
|
|
|
|
+ scheduler = sched.scheduler(time.time, time.sleep)
|
|
|
|
|
+ # 添加定时任务
|
|
|
|
|
+ scheduler.enter(wait_time, 1, save_all_proxy_ip, (page_size, total))
|
|
|
|
|
+ # 启动定时器
|
|
|
|
|
+ scheduler.run()
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+def get_external_ip():
|
|
|
|
|
+ # 获取公网出口IP地址
|
|
|
|
|
+ url = "https://api.ipify.org/?format=json" # 定义查询 API 的 URL
|
|
|
|
|
+ try:
|
|
|
|
|
+ response = urllib.request.urlopen(url) # 向查询 API 发送请求并获取响应
|
|
|
|
|
+ data = response.read() # 读取响应中的数据(字节流)
|
|
|
|
|
+ data = data.decode("utf-8") # 将响应数据从字节流转换为字符串
|
|
|
|
|
+ data = json.loads(data) # 将响应数据解析为 JSON 格式
|
|
|
|
|
+ public_ip = data["ip"] # 从 JSON 数据中提取公网IP地址
|
|
|
|
|
+ loggerKit.info(f"公网出口IP地址:{public_ip}")
|
|
|
|
|
+ return public_ip
|
|
|
|
|
+ except Exception as ex:
|
|
|
|
|
+ err_msg = "无法获取公网出口IP地址" # 查询失败时输出提示信息
|
|
|
|
|
+ loggerKit.error(f'err_msg: {err_msg}')
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+def redis_del_poc():
|
|
|
|
|
+ redis_client.delete('proxy_370')
|