mirror of
				https://github.com/shufflewzc/faker2.git
				synced 2025-10-31 20:22:49 +08:00 
			
		
		
		
	update
This commit is contained in:
		
							parent
							
								
									dc6b9bcb89
								
							
						
					
					
						commit
						7ace774e6f
					
				
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							| @ -26,7 +26,7 @@ try: | ||||
| except ImportError as e: | ||||
|     print(e) | ||||
|     if "No module" in str(e): | ||||
|         print("请先运行HarbourJ库依赖一键安装脚本(jd_check_dependent.py),安装jd_sign.so依赖") | ||||
|         print("请先运行Faker库依赖一键安装脚本(jd_check_dependent.py),安装jd_sign.so依赖") | ||||
| try: | ||||
|     from jdCookie import get_cookies | ||||
|     getCk = get_cookies() | ||||
|  | ||||
| @ -2,7 +2,7 @@ | ||||
| # -*- coding: utf-8 -*- | ||||
| 
 | ||||
| """ | ||||
| File: jd_joinCommon_opencard.py(通用开卡-customized系列) | ||||
| File: jd_joinCommon_opencard.py(通用开卡-joinCommon系列) | ||||
| Author: HarbourJ | ||||
| Date: 2022/8/12 20:37 | ||||
| TG: https://t.me/HarbourToulu | ||||
| @ -15,21 +15,19 @@ Description: dingzhi/joinCommon系列通用开卡脚本(通常情况下,开一 | ||||
|             变量: export jd_joinCommonId="2b870a1a7450xxxxxxxxxxxxx&1000000904" 变量值需要传入活动id&shopId | ||||
| """ | ||||
| 
 | ||||
| import time | ||||
| import requests | ||||
| import sys | ||||
| import re | ||||
| import os | ||||
| import time, requests, sys, re, os, json, random | ||||
| from datetime import datetime | ||||
| import json | ||||
| import random | ||||
| from urllib.parse import quote_plus, unquote_plus | ||||
| from functools import partial | ||||
| print = partial(print, flush=True) | ||||
| import warnings | ||||
| warnings.filterwarnings("ignore", category=DeprecationWarning) | ||||
| 
 | ||||
| from jd_sign import * | ||||
| try: | ||||
|     from jd_sign import * | ||||
| except ImportError as e: | ||||
|     print(e) | ||||
|     if "No module" in str(e): | ||||
|         print("请先运行Faker库依赖一键安装脚本(jd_check_dependent.py),安装jd_sign.so依赖") | ||||
| try: | ||||
|     from jdCookie import get_cookies | ||||
|     getCk = get_cookies() | ||||
| @ -38,6 +36,7 @@ except: | ||||
|     sys.exit(3) | ||||
| 
 | ||||
| redis_url = os.environ.get("redis_url") if os.environ.get("redis_url") else "172.17.0.1" | ||||
| redis_port = os.environ.get("redis_port") if os.environ.get("redis_port") else "6379" | ||||
| redis_pwd = os.environ.get("redis_pwd") if os.environ.get("redis_pwd") else "" | ||||
| jd_joinCommonId = os.environ.get("jd_joinCommonId") if os.environ.get("jd_joinCommonId") else "" | ||||
| inviterUuid = os.environ.get("jd_joinCommon_uuid") if os.environ.get("jd_joinCommon_uuid") else "" | ||||
| @ -63,7 +62,7 @@ def redis_conn(): | ||||
|     try: | ||||
|         import redis | ||||
|         try: | ||||
|             pool = redis.ConnectionPool(host=redis_url, port=6379, decode_responses=True, socket_connect_timeout=5, password=redis_pwd) | ||||
|             pool = redis.ConnectionPool(host=redis_url, port=redis_port, decode_responses=True, socket_connect_timeout=5, password=redis_pwd) | ||||
|             r = redis.Redis(connection_pool=pool) | ||||
|             r.get('conn_test') | ||||
|             print('✅redis连接成功') | ||||
| @ -81,17 +80,16 @@ def getToken(ck, r=None): | ||||
|         pt_pin = unquote_plus(re.compile(r'pt_pin=(.*?);').findall(ck)[0]) | ||||
|     except: | ||||
|         # redis缓存Token 活动域名+ck前7位(获取pin失败) | ||||
|         pt_pin = ck[:8] | ||||
|         pt_pin = ck[:15] | ||||
|     try: | ||||
|         if r is not None: | ||||
|             Token = r.get(f'{activityUrl.split("https://")[1].split("-")[0]}_{pt_pin}') | ||||
|             # print("Token过期时间", r.ttl(f'{activityUrl.split("https://")[1].split("-")[0]}_{pt_pin}')) | ||||
|             if Token is not None: | ||||
|                 # print(f"♻️获取缓存Token->: {Token}") | ||||
|                 print(f"♻️获取缓存Token") | ||||
|                 return Token | ||||
|             else: | ||||
|                 print("🈳去设置Token缓存") | ||||
|                 # print("🈳去设置Token缓存") | ||||
|                 s.headers = { | ||||
|                     'Connection': 'keep-alive', | ||||
|                     'Accept-Encoding': 'gzip, deflate, br', | ||||
| @ -115,9 +113,9 @@ def getToken(ck, r=None): | ||||
|                 Token_new = f.json()['token'] | ||||
|                 # print(f"Token->: {Token_new}") | ||||
|                 if r.set(f'{activityUrl.split("https://")[1].split("-")[0]}_{pt_pin}', Token_new, ex=1800): | ||||
|                     print("✅Token缓存设置成功") | ||||
|                     print("✅Token缓存成功") | ||||
|                 else: | ||||
|                     print("❌Token缓存设置失败") | ||||
|                     print("❌Token缓存失败") | ||||
|                 return Token_new | ||||
|         else: | ||||
|             s.headers = { | ||||
| @ -141,7 +139,7 @@ def getToken(ck, r=None): | ||||
|                 if "参数异常" in f.text: | ||||
|                     return | ||||
|             Token = f.json()['token'] | ||||
|             print(f"Token->: {Token}") | ||||
|             print(f"✅获取实时Token") | ||||
|             return Token | ||||
|     except: | ||||
|         return | ||||
|  | ||||
| @ -2,13 +2,13 @@ | ||||
| # -*- coding: utf-8 -*- | ||||
| 
 | ||||
| """ | ||||
| File: jd_shopCollectGift.py(一键领取京豆-店铺会员礼包) | ||||
| File: jd_shopCollectGift.py(店铺会员礼包-监控脚本) | ||||
| Author: HarbourJ | ||||
| Date: 2022/9/2 12:00 | ||||
| TG: https://t.me/HarbourToulu | ||||
| TgChat: https://t.me/HarbourSailing | ||||
| cron: 1 1 1 1 1 1 | ||||
| new Env('一键领取京豆-店铺会员礼包'); | ||||
| new Env('店铺会员礼包-JK'); | ||||
| ActivityEntry: https://shop.m.jd.com/shop/home?shopId=1000003443 | ||||
| Description: 部分账号开卡后无法自动领取开卡奖励,不自动开卡,仅领取已开卡的会员礼包 | ||||
|              变量export jd_shopCollectGiftId="1000003443" 变量为店铺venderId | ||||
| @ -21,13 +21,17 @@ print = partial(print, flush=True) | ||||
| import warnings | ||||
| warnings.filterwarnings("ignore", category=DeprecationWarning) | ||||
| from urllib.parse import quote_plus, unquote_plus | ||||
| 
 | ||||
| from jd_sign import * | ||||
| try: | ||||
|     from jd_sign import * | ||||
| except ImportError as e: | ||||
|     print(e) | ||||
|     if "No module" in str(e): | ||||
|         print("请先运行Faker库依赖一键安装脚本(jd_check_dependent.py),安装jd_sign.so依赖") | ||||
| try: | ||||
|     from jdCookie import get_cookies | ||||
|     getCk = get_cookies() | ||||
| except: | ||||
|     print("请先下载依赖脚本,\n下载链接: https://raw.githubusercontent.com/shufflewzc/faker2/main/jdCookie.py") | ||||
|     print("请先下载依赖脚本,\n下载链接: https://raw.githubusercontent.com/HarbourJ/HarbourToulu/main/jdCookie.py") | ||||
|     sys.exit(3) | ||||
| 
 | ||||
| venderId = os.environ.get("jd_shopCollectGiftId") if os.environ.get("jd_shopCollectGiftId") else "" | ||||
|  | ||||
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							
							
								
								
									
										41
									
								
								jd_wdz.py
									
									
									
									
									
								
							
							
						
						
									
										41
									
								
								jd_wdz.py
									
									
									
									
									
								
							| @ -2,34 +2,32 @@ | ||||
| # -*- coding: utf-8 -*- | ||||
| 
 | ||||
| """ | ||||
| File: jd_wdz.py(微定制组队瓜分) | ||||
| File: jd_wdz.py(微定制组队瓜分-监控脚本) | ||||
| Author: HarbourJ | ||||
| Date: 2022/8/12 20:37 | ||||
| TG: https://t.me/HarbourToulu | ||||
| TgChat: https://t.me/HarbourSailing | ||||
| cron: 1 1 1 1 1 1 | ||||
| new Env('微定制组队瓜分'); | ||||
| new Env('微定制组队瓜分-JK'); | ||||
| ActivityEntry: https://cjhydz-isv.isvjcloud.com/microDz/invite/activity/wx/view/index?activityId=eb24d792fdcf4732be29030f9fc8e007 | ||||
| Description: 微定制组队通用脚本 | ||||
|             本地sign算法+redis缓存Token+代理ip(自行配置,实测可行) | ||||
|             变量: export jd_wdz_activityId="eb24d792fdcf4732be29030f9fc8e007" | ||||
| """ | ||||
| 
 | ||||
| import time | ||||
| import requests | ||||
| import sys | ||||
| import re | ||||
| import os | ||||
| import time, requests, sys, re, os, json, random | ||||
| from datetime import datetime | ||||
| import json | ||||
| import random | ||||
| from urllib.parse import quote_plus, unquote_plus | ||||
| from functools import partial | ||||
| print = partial(print, flush=True) | ||||
| import warnings | ||||
| warnings.filterwarnings("ignore", category=DeprecationWarning) | ||||
| 
 | ||||
| from jd_sign import * | ||||
| try: | ||||
|     from jd_sign import * | ||||
| except ImportError as e: | ||||
|     print(e) | ||||
|     if "No module" in str(e): | ||||
|         print("请先运行Faker库依赖一键安装脚本(jd_check_dependent.py),安装jd_sign.so依赖") | ||||
| try: | ||||
|     from jdCookie import get_cookies | ||||
|     getCk = get_cookies() | ||||
| @ -38,6 +36,7 @@ except: | ||||
|     sys.exit(3) | ||||
| 
 | ||||
| redis_url = os.environ.get("redis_url") if os.environ.get("redis_url") else "172.17.0.1" | ||||
| redis_port = os.environ.get("redis_port") if os.environ.get("redis_port") else "6379" | ||||
| redis_pwd = os.environ.get("redis_pwd") if os.environ.get("redis_pwd") else "" | ||||
| jd_wdz_activityId = os.environ.get("jd_wdz_activityId") if os.environ.get("jd_wdz_activityId") else "" | ||||
| 
 | ||||
| @ -56,7 +55,7 @@ def redis_conn(): | ||||
|     try: | ||||
|         import redis | ||||
|         try: | ||||
|             pool = redis.ConnectionPool(host=redis_url, port=6379, decode_responses=True, socket_connect_timeout=5, password=redis_pwd) | ||||
|             pool = redis.ConnectionPool(host=redis_url, port=redis_port, decode_responses=True, socket_connect_timeout=5, password=redis_pwd) | ||||
|             r = redis.Redis(connection_pool=pool) | ||||
|             r.get('conn_test') | ||||
|             print('✅redis连接成功') | ||||
| @ -73,21 +72,17 @@ def getToken(ck, r=None): | ||||
|         # redis缓存Token 活动域名+pt_pin | ||||
|         pt_pin = unquote_plus(re.compile(r'pt_pin=(.*?);').findall(ck)[0]) | ||||
|     except: | ||||
|         # redis缓存Token 活动域名+ck前15位(获取pin失败) | ||||
|         if "pin=" in ck: | ||||
|             pt_pin = unquote_plus(re.compile(r'pin=(.*?);').findall(ck)[0]) | ||||
|         else: | ||||
|             pt_pin = ck[:15] | ||||
|         # redis缓存Token 活动域名+ck前7位(获取pin失败) | ||||
|         pt_pin = ck[:15] | ||||
|     try: | ||||
|         if r is not None: | ||||
|             Token = r.get(f'{activityUrl.split("https://")[1].split("-")[0]}_{pt_pin}') | ||||
|             # print("Token过期时间", r.ttl(f'{activityUrl.split("https://")[1].split("-")[0]}_{pt_pin}')) | ||||
|             if Token is not None: | ||||
|                 # print(f"♻️获取缓存Token->: {Token}") | ||||
|                 print(f"♻️获取缓存Token") | ||||
|                 return Token | ||||
|             else: | ||||
|                 print("🈳去设置Token缓存") | ||||
|                 # print("🈳去设置Token缓存") | ||||
|                 s.headers = { | ||||
|                     'Connection': 'keep-alive', | ||||
|                     'Accept-Encoding': 'gzip, deflate, br', | ||||
| @ -111,9 +106,9 @@ def getToken(ck, r=None): | ||||
|                 Token_new = f.json()['token'] | ||||
|                 # print(f"Token->: {Token_new}") | ||||
|                 if r.set(f'{activityUrl.split("https://")[1].split("-")[0]}_{pt_pin}', Token_new, ex=1800): | ||||
|                     print("✅Token缓存设置成功") | ||||
|                     print("✅Token缓存成功") | ||||
|                 else: | ||||
|                     print("❌Token缓存设置失败") | ||||
|                     print("❌Token缓存失败") | ||||
|                 return Token_new | ||||
|         else: | ||||
|             s.headers = { | ||||
| @ -137,7 +132,7 @@ def getToken(ck, r=None): | ||||
|                 if "参数异常" in f.text: | ||||
|                     return | ||||
|             Token = f.json()['token'] | ||||
|             print(f"Token->: {Token}") | ||||
|             print(f"✅获取实时Token") | ||||
|             return Token | ||||
|     except: | ||||
|         return | ||||
| @ -357,7 +352,7 @@ def acceptInvite(inviterNick, inviterPin, inviterImg, pin, nickName, inviteeImg) | ||||
|         inviteeImg = quote_plus(inviteeImg) | ||||
|     except: | ||||
|         inviteeImg = quote_plus("https://img10.360buyimg.com/imgzone/jfs/t1/21383/2/6633/3879/5c5138d8E0967ccf2/91da57c5e2166005.jpg") | ||||
|     payload = f"activityId={activityId}&inviter={quote_plus(quote_plus(inviterPin))}&inviterImg={quote_plus(inviterImg)}&inviterNick={quote_plus(inviterNick)}&invitee={quote_plus(quote_plus(pin))}&inviteeImg={quote_plus(inviteeImg)}&inviteeNick={quote_plus(nickName)}" | ||||
|     payload = f"activityId={activityId}&inviter={quote_plus(quote_plus(inviterPin))}&inviterImg={inviterImg}&inviterNick={quote_plus(inviterNick)}&invitee={quote_plus(quote_plus(pin))}&inviteeImg={inviteeImg}&inviteeNick={quote_plus(nickName)}" | ||||
|     headers = { | ||||
|         'Host': 'cjhy-isv.isvjcloud.com', | ||||
|         'Accept': 'application/json', | ||||
|  | ||||
| @ -2,39 +2,38 @@ | ||||
| # -*- coding: utf-8 -*- | ||||
| 
 | ||||
| """ | ||||
| File: jd_wxBirthGifts.py(生日礼包) | ||||
| File: jd_wxBirthGifts.py(生日礼包-监控脚本) | ||||
| Author: HarbourJ | ||||
| Date: 2022/8/8 19:52 | ||||
| TG: https://t.me/HarbourToulu | ||||
| TgChat: https://t.me/HarbourSailing | ||||
| cron: 1 1 1 1 1 1 | ||||
| new Env('生日礼包'); | ||||
| new Env('生日礼包-JK'); | ||||
| ActivityEntry: https://cjhy-isv.isvjcloud.com/mc/wxMcLevelAndBirthGifts/activity?activityId=f3325e3375a14866xxxxxxxxxxxx | ||||
|                变量 export jd_wxBirthGiftsId="f3325e3375a14866xxxxxxxxxxxx" | ||||
| """ | ||||
| 
 | ||||
| import time | ||||
| import requests | ||||
| import sys | ||||
| import re | ||||
| import os | ||||
| import time, requests, sys, re, os, json, random | ||||
| from datetime import datetime | ||||
| import json | ||||
| import random | ||||
| from urllib.parse import quote_plus, unquote_plus | ||||
| from functools import partial | ||||
| print = partial(print, flush=True) | ||||
| import warnings | ||||
| warnings.filterwarnings("ignore", category=DeprecationWarning) | ||||
| 
 | ||||
| from jd_sign import * | ||||
| try: | ||||
|     from jd_sign import * | ||||
| except ImportError as e: | ||||
|     print(e) | ||||
|     if "No module" in str(e): | ||||
|         print("请先运行Faker库依赖一键安装脚本(jd_check_dependent.py),安装jd_sign.so依赖") | ||||
| try: | ||||
|     from jdCookie import get_cookies | ||||
|     getCk = get_cookies() | ||||
| except: | ||||
|     print("请先下载依赖脚本,\n下载链接: https://raw.githubusercontent.com/shufflewzc/faker2/main/jdCookie.py") | ||||
|     print("请先下载依赖脚本,\n下载链接: https://raw.githubusercontent.com/HarbourJ/HarbourToulu/main/jdCookie.py") | ||||
|     sys.exit(3) | ||||
| redis_url = os.environ.get("redis_url") if os.environ.get("redis_url") else "172.17.0.1" | ||||
| redis_port = os.environ.get("redis_port") if os.environ.get("redis_port") else "6379" | ||||
| redis_pwd = os.environ.get("redis_pwd") if os.environ.get("redis_pwd") else "" | ||||
| activityId = os.environ.get("jd_wxBirthGiftsId") if os.environ.get("jd_wxBirthGiftsId") else "" | ||||
| 
 | ||||
| @ -54,7 +53,7 @@ def redis_conn(): | ||||
|                 os.system("pip install redis") | ||||
|             import redis | ||||
|         try: | ||||
|             pool = redis.ConnectionPool(host=redis_url, port=6379, decode_responses=True, socket_connect_timeout=5, password=redis_pwd) | ||||
|             pool = redis.ConnectionPool(host=redis_url, port=redis_port, decode_responses=True, socket_connect_timeout=5, password=redis_pwd) | ||||
|             r = redis.Redis(connection_pool=pool) | ||||
|             r.get('conn_test') | ||||
|             print('✅redis连接成功') | ||||
| @ -72,17 +71,44 @@ def getToken(ck, r=None): | ||||
|         pt_pin = unquote_plus(re.compile(r'pt_pin=(.*?);').findall(ck)[0]) | ||||
|     except: | ||||
|         # redis缓存Token 活动域名+ck前7位(获取pin失败) | ||||
|         pt_pin = ck[:8] | ||||
| 
 | ||||
|     if r is not None: | ||||
|         Token = r.get(f'{activityUrl.split("https://")[1].split("-")[0]}_{pt_pin}') | ||||
|         # print("Token过期时间", r.ttl(f'{activityUrl.split("https://")[1].split("-")[0]}_{pt_pin}')) | ||||
|         if Token is not None: | ||||
|             # print(f"♻️获取缓存Token->: {Token}") | ||||
|             print(f"♻️获取缓存Token") | ||||
|             return Token | ||||
|         pt_pin = ck[:15] | ||||
|     try: | ||||
|         if r is not None: | ||||
|             Token = r.get(f'{activityUrl.split("https://")[1].split("-")[0]}_{pt_pin}') | ||||
|             # print("Token过期时间", r.ttl(f'{activityUrl.split("https://")[1].split("-")[0]}_{pt_pin}')) | ||||
|             if Token is not None: | ||||
|                 print(f"♻️获取缓存Token") | ||||
|                 return Token | ||||
|             else: | ||||
|                 # print("🈳去设置Token缓存") | ||||
|                 s.headers = { | ||||
|                     'Connection': 'keep-alive', | ||||
|                     'Accept-Encoding': 'gzip, deflate, br', | ||||
|                     'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8', | ||||
|                     'User-Agent': '', | ||||
|                     'Cookie': ck, | ||||
|                     'Host': 'api.m.jd.com', | ||||
|                     'Referer': '', | ||||
|                     'Accept-Language': 'zh-Hans-CN;q=1 en-CN;q=0.9', | ||||
|                     'Accept': '*/*' | ||||
|                 } | ||||
|                 sign_txt = sign({"url": f"{host}", "id": ""}, 'isvObfuscator') | ||||
|                 # print(sign_txt) | ||||
|                 f = s.post('https://api.m.jd.com/client.action', verify=False, timeout=30) | ||||
|                 if f.status_code != 200: | ||||
|                     print(f.status_code) | ||||
|                     return | ||||
|                 else: | ||||
|                     if "参数异常" in f.text: | ||||
|                         return | ||||
|                 Token_new = f.json()['token'] | ||||
|                 # print(f"Token->: {Token_new}") | ||||
|                 if r.set(f'{activityUrl.split("https://")[1].split("-")[0]}_{pt_pin}', Token_new, ex=1800): | ||||
|                     print("✅Token缓存成功") | ||||
|                 else: | ||||
|                     print("❌Token缓存失败") | ||||
|                 return Token_new | ||||
|         else: | ||||
|             print("🈳去设置Token缓存") | ||||
|             s.headers = { | ||||
|                 'Connection': 'keep-alive', | ||||
|                 'Accept-Encoding': 'gzip, deflate, br', | ||||
| @ -103,37 +129,11 @@ def getToken(ck, r=None): | ||||
|             else: | ||||
|                 if "参数异常" in f.text: | ||||
|                     return | ||||
|             Token_new = f.json()['token'] | ||||
|             # print(f"Token->: {Token_new}") | ||||
|             if r.set(f'{activityUrl.split("https://")[1].split("-")[0]}_{pt_pin}', Token_new, ex=1800): | ||||
|                 print("✅Token缓存设置成功") | ||||
|             else: | ||||
|                 print("❌Token缓存设置失败") | ||||
|             return Token_new | ||||
|     else: | ||||
|         s.headers = { | ||||
|             'Connection': 'keep-alive', | ||||
|             'Accept-Encoding': 'gzip, deflate, br', | ||||
|             'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8', | ||||
|             'User-Agent': '', | ||||
|             'Cookie': ck, | ||||
|             'Host': 'api.m.jd.com', | ||||
|             'Referer': '', | ||||
|             'Accept-Language': 'zh-Hans-CN;q=1 en-CN;q=0.9', | ||||
|             'Accept': '*/*' | ||||
|         } | ||||
|         sign_txt = sign({"url": f"{host}", "id": ""}, 'isvObfuscator') | ||||
|         # print(sign_txt) | ||||
|         f = s.post('https://api.m.jd.com/client.action', verify=False, timeout=30) | ||||
|         if f.status_code != 200: | ||||
|             print(f.status_code) | ||||
|             return | ||||
|         else: | ||||
|             if "参数异常" in f.text: | ||||
|                 return | ||||
|         Token = f.json()['token'] | ||||
|         print(f"Token->: {Token}") | ||||
|         return Token | ||||
|             Token = f.json()['token'] | ||||
|             print(f"✅获取实时Token") | ||||
|             return Token | ||||
|     except: | ||||
|         return | ||||
| 
 | ||||
| def getJdTime(): | ||||
|     jdTime = int(round(time.time() * 1000)) | ||||
|  | ||||
							
								
								
									
										614
									
								
								jd_wxCollectionActivity.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										614
									
								
								jd_wxCollectionActivity.py
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,614 @@ | ||||
| #!/usr/bin/env python3 | ||||
| # -*- coding: utf-8 -*- | ||||
| 
 | ||||
| """ | ||||
| File: jd_wxBulidActivity.py(加购有礼-监控脚本) | ||||
| Author: HarbourJ | ||||
| Date: 2022/9/18 19:52 | ||||
| TG: https://t.me/HarbourToulu | ||||
| TgChat: https://t.me/HarbourSailing | ||||
| cron: 1 1 1 1 1 1 | ||||
| new Env('加购有礼-JK') | ||||
| ActivityEntry: https://lzkj-isv.isvjd.com/wxCollectionActivity/activity2/df1bcc4c1e894444ae7579e124149999?activityId=df1bcc4c1e894444ae7579e124149999 | ||||
| Description: 本地sign算法+redis缓存Token | ||||
|              变量: export jd_wxCollectionActivityUrl="https://lzkj-isv.isvjd.com/wxCollectionActivity/activity2/xxx?activityId=xxx" 变量值需要传入完整活动地址 | ||||
| """ | ||||
| 
 | ||||
| import time, requests, sys, re, os, json, random | ||||
| from datetime import datetime | ||||
| from urllib.parse import quote_plus, unquote_plus | ||||
| from functools import partial | ||||
| print = partial(print, flush=True) | ||||
| import warnings | ||||
| warnings.filterwarnings("ignore", category=DeprecationWarning) | ||||
| try: | ||||
|     from jd_sign import * | ||||
| except ImportError as e: | ||||
|     print(e) | ||||
|     if "No module" in str(e): | ||||
|         print("请先运行Faker库依赖一键安装脚本(jd_check_dependent.py),安装jd_sign.so依赖") | ||||
| try: | ||||
|     from jdCookie import get_cookies | ||||
|     getCk = get_cookies() | ||||
| except: | ||||
|     print("请先下载依赖脚本,\n下载链接: https://raw.githubusercontent.com/HarbourJ/HarbourToulu/main/jdCookie.py") | ||||
|     sys.exit(3) | ||||
| redis_url = os.environ.get("redis_url") if os.environ.get("redis_url") else "172.17.0.1" | ||||
| redis_port = os.environ.get("redis_port") if os.environ.get("redis_port") else "6379" | ||||
| redis_pwd = os.environ.get("redis_pwd") if os.environ.get("redis_pwd") else "" | ||||
| activity_url = os.environ.get("jd_wxCollectionActivityUrl") if os.environ.get("jd_wxCollectionActivityUrl") else "" | ||||
| runNums = os.environ.get("jd_wxCollectionActivityRunNums") if os.environ.get("jd_wxCollectionActivityRunNums") else 10 | ||||
| 
 | ||||
| if not activity_url or "wxCollectionActivity/activity" not in activity_url: | ||||
|     print("⚠️未发现有效加购有礼活动变量,退出程序!") | ||||
|     sys.exit() | ||||
| activityUrl = activity_url.replace('isvjd', 'isvjcloud').split('&')[0] | ||||
| activityId = activityUrl.split('activityId=')[1] | ||||
| print(f"【🛳活动入口】{activityUrl}\n") | ||||
| runNums = int(runNums) | ||||
| if runNums == 10: | ||||
|     print('🤖本次加购默认跑前10个账号,设置自定义变量:export jd_wxCollectionActivityRunNums="需要运行加购的ck数量"') | ||||
| else: | ||||
|     print(f'🤖本次运行前{runNums}个账号') | ||||
| 
 | ||||
| 
 | ||||
| def redis_conn(): | ||||
|     try: | ||||
|         import redis | ||||
|         try: | ||||
|             pool = redis.ConnectionPool(host=redis_url, port=redis_port, decode_responses=True, socket_connect_timeout=5, password=redis_pwd) | ||||
|             r = redis.Redis(connection_pool=pool) | ||||
|             r.get('conn_test') | ||||
|             print('✅redis连接成功') | ||||
|             return r | ||||
|         except: | ||||
|             print("⚠️redis连接异常") | ||||
|     except: | ||||
|         print("⚠️缺少redis依赖,请运行pip3 install redis") | ||||
|         sys.exit() | ||||
| 
 | ||||
| def getToken(ck, r=None): | ||||
|     host = f'{activityUrl.split("com/")[0]}com' | ||||
|     try: | ||||
|         # redis缓存Token 活动域名+pt_pin | ||||
|         pt_pin = unquote_plus(re.compile(r'pt_pin=(.*?);').findall(ck)[0]) | ||||
|     except: | ||||
|         # redis缓存Token 活动域名+ck前7位(获取pin失败) | ||||
|         pt_pin = ck[:15] | ||||
|     try: | ||||
|         if r is not None: | ||||
|             Token = r.get(f'{activityUrl.split("https://")[1].split("-")[0]}_{pt_pin}') | ||||
|             # print("Token过期时间", r.ttl(f'{activityUrl.split("https://")[1].split("-")[0]}_{pt_pin}')) | ||||
|             if Token is not None: | ||||
|                 print(f"♻️获取缓存Token") | ||||
|                 return Token | ||||
|             else: | ||||
|                 # print("🈳去设置Token缓存") | ||||
|                 s.headers = { | ||||
|                     'Connection': 'keep-alive', | ||||
|                     'Accept-Encoding': 'gzip, deflate, br', | ||||
|                     'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8', | ||||
|                     'User-Agent': '', | ||||
|                     'Cookie': ck, | ||||
|                     'Host': 'api.m.jd.com', | ||||
|                     'Referer': '', | ||||
|                     'Accept-Language': 'zh-Hans-CN;q=1 en-CN;q=0.9', | ||||
|                     'Accept': '*/*' | ||||
|                 } | ||||
|                 sign_txt = sign({"url": f"{host}", "id": ""}, 'isvObfuscator') | ||||
|                 # print(sign_txt) | ||||
|                 f = s.post('https://api.m.jd.com/client.action', verify=False, timeout=30) | ||||
|                 if f.status_code != 200: | ||||
|                     print(f.status_code) | ||||
|                     return | ||||
|                 else: | ||||
|                     if "参数异常" in f.text: | ||||
|                         return | ||||
|                 Token_new = f.json()['token'] | ||||
|                 # print(f"Token->: {Token_new}") | ||||
|                 if r.set(f'{activityUrl.split("https://")[1].split("-")[0]}_{pt_pin}', Token_new, ex=1800): | ||||
|                     print("✅Token缓存成功") | ||||
|                 else: | ||||
|                     print("❌Token缓存失败") | ||||
|                 return Token_new | ||||
|         else: | ||||
|             s.headers = { | ||||
|                 'Connection': 'keep-alive', | ||||
|                 'Accept-Encoding': 'gzip, deflate, br', | ||||
|                 'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8', | ||||
|                 'User-Agent': '', | ||||
|                 'Cookie': ck, | ||||
|                 'Host': 'api.m.jd.com', | ||||
|                 'Referer': '', | ||||
|                 'Accept-Language': 'zh-Hans-CN;q=1 en-CN;q=0.9', | ||||
|                 'Accept': '*/*' | ||||
|             } | ||||
|             sign_txt = sign({"url": f"{host}", "id": ""}, 'isvObfuscator') | ||||
|             # print(sign_txt) | ||||
|             f = s.post('https://api.m.jd.com/client.action', verify=False, timeout=30) | ||||
|             if f.status_code != 200: | ||||
|                 print(f.status_code) | ||||
|                 return | ||||
|             else: | ||||
|                 if "参数异常" in f.text: | ||||
|                     return | ||||
|             Token = f.json()['token'] | ||||
|             print(f"✅获取实时Token") | ||||
|             return Token | ||||
|     except: | ||||
|         return | ||||
| 
 | ||||
| def getJdTime(): | ||||
|     jdTime = int(round(time.time() * 1000)) | ||||
|     return jdTime | ||||
| 
 | ||||
| def randomString(e, flag=False): | ||||
|     t = "0123456789abcdef" | ||||
|     if flag: t = t.upper() | ||||
|     n = [random.choice(t) for _ in range(e)] | ||||
|     return ''.join(n) | ||||
| 
 | ||||
| def refresh_cookies(res): | ||||
|     if res.cookies: | ||||
|         cookies = res.cookies.get_dict() | ||||
|         set_cookie = [(set_cookie + "=" + cookies[set_cookie]) for set_cookie in cookies] | ||||
|         global activityCookie | ||||
|         activityCookieMid = [i for i in activityCookie.split(';') if i != ''] | ||||
|         for i in activityCookieMid: | ||||
|             for x in set_cookie: | ||||
|                 if i.split('=')[0] == x.split('=')[0]: | ||||
|                     if i.split('=')[1] != x.split('=')[1]: | ||||
|                         activityCookieMid.remove(i) | ||||
|         activityCookie = ''.join(sorted([(set_cookie + ";") for set_cookie in list(set(activityCookieMid + set_cookie))])) | ||||
| 
 | ||||
| def getActivity(): | ||||
|     url = activityUrl | ||||
|     headers = { | ||||
|         'Host': 'lzkj-isv.isvjcloud.com', | ||||
|         'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8', | ||||
|         'User-Agent': ua, | ||||
|         'Accept-Language': 'zh-CN,zh-Hans;q=0.9', | ||||
|         'Accept-Encoding': 'gzip, deflate, br', | ||||
|         'Connection': 'keep-alive' | ||||
|     } | ||||
|     response = requests.request("GET", url, headers=headers) | ||||
|     if response.status_code == 200: | ||||
|         if response.cookies: | ||||
|             cookies = response.cookies.get_dict() | ||||
|             set_cookies = [(set_cookie + "=" + cookies[set_cookie]) for set_cookie in cookies] | ||||
|             set_cookie = ''.join(sorted([(set_cookie + ";") for set_cookie in set_cookies])) | ||||
|         res = response.text | ||||
|         if "活动已结束" in res: | ||||
|             print("⛈活动已结束,下次早点来~") | ||||
|             sys.exit() | ||||
|         if "关注" in res and "加购" not in res: | ||||
|             activityType = 5 | ||||
|         else: | ||||
|             activityType = 6 | ||||
|         return set_cookie, activityType | ||||
|     else: | ||||
|         print(response.status_code, "⚠️疑似ip黑了") | ||||
|         sys.exit() | ||||
| 
 | ||||
| def getSystemConfigForNew(activityType): | ||||
|     url = "https://lzkj-isv.isvjcloud.com/wxCommonInfo/getSystemConfigForNew" | ||||
|     payload = f'activityId={activityId}&activityType={activityType}' | ||||
|     headers = { | ||||
|         'Host': 'lzkj-isv.isvjcloud.com', | ||||
|         'Accept': 'application/json', | ||||
|         'X-Requested-With': 'XMLHttpRequest', | ||||
|         'Accept-Language': 'zh-CN,zh-Hans;q=0.9', | ||||
|         'Accept-Encoding': 'gzip, deflate, br', | ||||
|         'Content-Type': 'application/x-www-form-urlencoded', | ||||
|         'Origin': 'https://lzkj-isv.isvjcloud.com', | ||||
|         'User-Agent': ua, | ||||
|         'Connection': 'keep-alive', | ||||
|         'Referer': activityUrl, | ||||
|         'Cookie': activityCookie | ||||
|     } | ||||
|     response = requests.request("POST", url, headers=headers, data=payload) | ||||
|     refresh_cookies(response) | ||||
| 
 | ||||
| def getSimpleActInfoVo(): | ||||
|     url = "https://lzkj-isv.isvjcloud.com/customer/getSimpleActInfoVo" | ||||
|     payload = f"activityId={activityId}" | ||||
|     headers = { | ||||
|         'Host': 'lzkj-isv.isvjcloud.com', | ||||
|         'Accept': 'application/json', | ||||
|         'X-Requested-With': 'XMLHttpRequest', | ||||
|         'Accept-Language': 'zh-CN,zh-Hans;q=0.9', | ||||
|         'Accept-Encoding': 'gzip, deflate, br', | ||||
|         'Content-Type': 'application/x-www-form-urlencoded', | ||||
|         'Origin': 'https://lzkj-isv.isvjcloud.com', | ||||
|         'User-Agent': ua, | ||||
|         'Connection': 'keep-alive', | ||||
|         'Referer': activityUrl, | ||||
|         'Cookie': activityCookie | ||||
|     } | ||||
|     response = requests.request("POST", url, headers=headers, data=payload) | ||||
|     refresh_cookies(response) | ||||
|     res = response.json() | ||||
|     if res['result']: | ||||
|         return res['data'] | ||||
| 
 | ||||
| def getMyPing(venderId): | ||||
|     url = "https://lzkj-isv.isvjcloud.com/customer/getMyPing" | ||||
|     payload = f"userId={venderId}&token={token}&fromType=APP" | ||||
|     headers = { | ||||
|         'Host': 'lzkj-isv.isvjcloud.com', | ||||
|         'Accept': 'application/json', | ||||
|         'X-Requested-With': 'XMLHttpRequest', | ||||
|         'Accept-Language': 'zh-CN,zh-Hans;q=0.9', | ||||
|         'Accept-Encoding': 'gzip, deflate, br', | ||||
|         'Content-Type': 'application/x-www-form-urlencoded', | ||||
|         'Origin': 'https://lzkj-isv.isvjcloud.com', | ||||
|         'User-Agent': ua, | ||||
|         'Connection': 'keep-alive', | ||||
|         'Referer': activityUrl, | ||||
|         'Cookie': activityCookie | ||||
|     } | ||||
|     response = requests.request("POST", url, headers=headers, data=payload) | ||||
|     refresh_cookies(response) | ||||
|     res = response.json() | ||||
|     if res['result']: | ||||
|         return res['data']['nickname'], res['data']['secretPin'] | ||||
|     else: | ||||
|         print(f"⚠️{res['errorMessage']}") | ||||
| 
 | ||||
| def accessLogWithAD(venderId, pin, activityType): | ||||
|     url = "https://lzkj-isv.isvjcloud.com/common/accessLogWithAD" | ||||
|     payload = f"venderId={venderId}&code={activityType}&pin={quote_plus(pin)}&activityId={activityId}&pageUrl={quote_plus(activityUrl)}&subType=app&adSource=" | ||||
|     headers = { | ||||
|         'Host': 'lzkj-isv.isvjcloud.com', | ||||
|         'Accept': 'application/json', | ||||
|         'X-Requested-With': 'XMLHttpRequest', | ||||
|         'Accept-Language': 'zh-CN,zh-Hans;q=0.9', | ||||
|         'Accept-Encoding': 'gzip, deflate, br', | ||||
|         'Content-Type': 'application/x-www-form-urlencoded', | ||||
|         'Origin': 'https://lzkj-isv.isvjcloud.com', | ||||
|         'User-Agent': ua, | ||||
|         'Connection': 'keep-alive', | ||||
|         'Referer': activityUrl, | ||||
|         'Cookie': activityCookie | ||||
|     } | ||||
|     response = requests.request("POST", url, headers=headers, data=payload) | ||||
|     refresh_cookies(response) | ||||
| 
 | ||||
| def activityContent(pin): | ||||
|     url = "https://lzkj-isv.isvjcloud.com/wxCollectionActivity/activityContent" | ||||
|     payload = f"activityId={activityId}&pin={quote_plus(pin)}" | ||||
|     headers = { | ||||
|         'Host': 'lzkj-isv.isvjcloud.com', | ||||
|         'Accept': 'application/json', | ||||
|         'X-Requested-With': 'XMLHttpRequest', | ||||
|         'Accept-Language': 'zh-CN,zh-Hans;q=0.9', | ||||
|         'Accept-Encoding': 'gzip, deflate, br', | ||||
|         'Content-Type': 'application/x-www-form-urlencoded', | ||||
|         'Origin': 'https://lzkj-isv.isvjcloud.com', | ||||
|         'User-Agent': ua, | ||||
|         'Connection': 'keep-alive', | ||||
|         'Referer': activityUrl, | ||||
|         'Cookie': activityCookie | ||||
|     } | ||||
|     response = requests.request("POST", url, headers=headers, data=payload) | ||||
|     # refresh_cookies(response) | ||||
|     res = response.json() | ||||
|     if res['result']: | ||||
|         needCollectionSize = res['data']['needCollectionSize'] | ||||
|         hasCollectionSize = res['data']['hasCollectionSize'] | ||||
|         needFollow = res['data']['needFollow'] | ||||
|         hasFollow = res['data']['hasFollow'] | ||||
|         cpvos = res['data']['cpvos'] | ||||
|         drawInfo = res['data']['drawInfo'] | ||||
|         drawOk = drawInfo['drawOk'] | ||||
|         priceName = drawInfo['name'] | ||||
|         oneKeyAddCart = res['data']['oneKeyAddCart'] | ||||
|         return needCollectionSize, hasCollectionSize, needFollow, hasFollow, cpvos, drawOk, priceName, oneKeyAddCart | ||||
|     else: | ||||
|         print(f"⛈{res['errorMessage']}") | ||||
|         sys.exit() | ||||
| 
 | ||||
| def shopInfo(): | ||||
|     url = "https://lzkj-isv.isvjcloud.com/wxCollectionActivity/shopInfo" | ||||
|     payload = f"activityId={activityId}" | ||||
|     headers = { | ||||
|         'Host': 'lzkj-isv.isvjcloud.com', | ||||
|         'Accept': 'application/json', | ||||
|         'X-Requested-With': 'XMLHttpRequest', | ||||
|         'Accept-Language': 'zh-CN,zh-Hans;q=0.9', | ||||
|         'Accept-Encoding': 'gzip, deflate, br', | ||||
|         'Content-Type': 'application/x-www-form-urlencoded', | ||||
|         'Origin': 'https://lzkj-isv.isvjcloud.com', | ||||
|         'User-Agent': ua, | ||||
|         'Connection': 'keep-alive', | ||||
|         'Referer': activityUrl, | ||||
|         'Cookie': activityCookie | ||||
|     } | ||||
|     response = requests.request("POST", url, headers=headers, data=payload) | ||||
|     refresh_cookies(response) | ||||
|     res = response.json() | ||||
|     if res['result']: | ||||
|         shopName = res['data']['shopName'] | ||||
|         return shopName | ||||
|     else: | ||||
|         print(f"⛈{res['errorMessage']}") | ||||
| 
 | ||||
| def getActMemberInfo(venderId, pin): | ||||
|     url = "https://lzkj-isv.isvjcloud.com/wxCommonInfo/getActMemberInfo" | ||||
|     payload = f"venderId={venderId}&activityId={activityId}&pin={quote_plus(pin)}" | ||||
|     headers = { | ||||
|         'Host': 'lzkj-isv.isvjcloud.com', | ||||
|         'Accept': 'application/json', | ||||
|         'X-Requested-With': 'XMLHttpRequest', | ||||
|         'Accept-Language': 'zh-CN,zh-Hans;q=0.9', | ||||
|         'Accept-Encoding': 'gzip, deflate, br', | ||||
|         'Content-Type': 'application/x-www-form-urlencoded', | ||||
|         'Origin': 'https://lzkj-isv.isvjcloud.com', | ||||
|         'User-Agent': ua, | ||||
|         'Connection': 'keep-alive', | ||||
|         'Referer': activityUrl, | ||||
|         'Cookie': activityCookie | ||||
|     } | ||||
|     response = requests.request("POST", url, headers=headers, data=payload) | ||||
|     # refresh_cookies(response) | ||||
|     res = response.json() | ||||
|     print(res) | ||||
|     if res['result']: | ||||
|         openCard = res['data']['openCard'] | ||||
|         return openCard | ||||
|     else: | ||||
|         print(f"⛈{res['errorMessage']}") | ||||
| 
 | ||||
| def followShop(venderId, pin, activityType): | ||||
|     url = "https://lzkj-isv.isvjcloud.com/wxActionCommon/followShop" | ||||
|     payload = f"userId={venderId}&activityId={activityId}&buyerNick={quote_plus(pin)}&activityType={activityType}" | ||||
|     headers = { | ||||
|         'Host': 'lzkj-isv.isvjcloud.com', | ||||
|         'Accept': 'application/json', | ||||
|         'X-Requested-With': 'XMLHttpRequest', | ||||
|         'Accept-Language': 'zh-CN,zh-Hans;q=0.9', | ||||
|         'Accept-Encoding': 'gzip, deflate, br', | ||||
|         'Content-Type': 'application/x-www-form-urlencoded', | ||||
|         'Origin': 'https://lzkj-isv.isvjcloud.com', | ||||
|         'User-Agent': ua, | ||||
|         'Connection': 'keep-alive', | ||||
|         'Referer': activityUrl, | ||||
|         'Cookie': activityCookie | ||||
|     } | ||||
|     response = requests.request("POST", url, headers=headers, data=payload) | ||||
|     refresh_cookies(response) | ||||
|     res = response.json() | ||||
|     if res['result']: | ||||
|         hasFollowShop = res['data'] | ||||
|         return hasFollowShop | ||||
|     else: | ||||
|         print(f"⛈{res['errorMessage']}") | ||||
| 
 | ||||
| def getInfo(): | ||||
|     url = f"https://lzkj-isv.isvjcloud.com/miniProgramShareInfo/getInfo?activityId={activityId}" | ||||
|     headers = { | ||||
|         'Host': 'lzkj-isv.isvjcloud.com', | ||||
|         'Accept': 'application/json', | ||||
|         'X-Requested-With': 'XMLHttpRequest', | ||||
|         'Accept-Language': 'zh-CN,zh-Hans;q=0.9', | ||||
|         'Accept-Encoding': 'gzip, deflate, br', | ||||
|         'User-Agent': ua, | ||||
|         'Connection': 'keep-alive', | ||||
|         'Referer': activityUrl, | ||||
|         'Cookie': activityCookie | ||||
|     } | ||||
|     response = requests.request("GET", url, headers=headers) | ||||
|     refresh_cookies(response) | ||||
| 
 | ||||
| def addCard(productId, pin): | ||||
|     """加购""" | ||||
|     url = "https://lzkj-isv.isvjcloud.com/wxCollectionActivity/addCart" | ||||
|     payload = f"productId={productId}&activityId={activityId}&pin={quote_plus(pin)}" | ||||
|     headers = { | ||||
|         'Host': 'lzkj-isv.isvjcloud.com', | ||||
|         'Accept': 'application/json', | ||||
|         'X-Requested-With': 'XMLHttpRequest', | ||||
|         'Accept-Language': 'zh-CN,zh-Hans;q=0.9', | ||||
|         'Accept-Encoding': 'gzip, deflate, br', | ||||
|         'Content-Type': 'application/x-www-form-urlencoded', | ||||
|         'Origin': 'https://lzkj-isv.isvjcloud.com', | ||||
|         'User-Agent': ua, | ||||
|         'Connection': 'keep-alive', | ||||
|         'Referer': activityUrl, | ||||
|         'Cookie': activityCookie | ||||
|     } | ||||
|     response = requests.request("POST", url, headers=headers, data=payload) | ||||
|     refresh_cookies(response) | ||||
|     res = response.json() | ||||
|     if res['result']: | ||||
|         hasAddCartSize = res['data']['hasAddCartSize'] | ||||
|         return hasAddCartSize | ||||
|     else: | ||||
|         print(f"⛈{res['errorMessage']}") | ||||
| 
 | ||||
| def collection(productId, pin): | ||||
|     """关注""" | ||||
|     url = "https://lzkj-isv.isvjcloud.com/wxCollectionActivity/collection" | ||||
|     payload = f"productId={productId}&activityId={activityId}&pin={quote_plus(pin)}" | ||||
|     headers = { | ||||
|         'Host': 'lzkj-isv.isvjcloud.com', | ||||
|         'Accept': 'application/json', | ||||
|         'X-Requested-With': 'XMLHttpRequest', | ||||
|         'Accept-Language': 'zh-CN,zh-Hans;q=0.9', | ||||
|         'Accept-Encoding': 'gzip, deflate, br', | ||||
|         'Content-Type': 'application/x-www-form-urlencoded', | ||||
|         'Origin': 'https://lzkj-isv.isvjcloud.com', | ||||
|         'User-Agent': ua, | ||||
|         'Connection': 'keep-alive', | ||||
|         'Referer': activityUrl, | ||||
|         'Cookie': activityCookie | ||||
|     } | ||||
|     response = requests.request("POST", url, headers=headers, data=payload) | ||||
|     refresh_cookies(response) | ||||
|     res = response.json() | ||||
|     if res['result']: | ||||
|         hasCollectionSize = res['data']['hasCollectionSize'] | ||||
|         return hasCollectionSize | ||||
|     else: | ||||
|         print(f"⛈{res['errorMessage']}") | ||||
| 
 | ||||
| def oneKeyAdd(productIds, pin): | ||||
|     """一键加购""" | ||||
|     url = "https://lzkj-isv.isvjcloud.com/wxCollectionActivity/oneKeyAddCart" | ||||
|     payload = f"productIds={productIds}&activityId={activityId}&pin={quote_plus(pin)}" | ||||
|     headers = { | ||||
|         'Host': 'lzkj-isv.isvjcloud.com', | ||||
|         'Accept': 'application/json', | ||||
|         'X-Requested-With': 'XMLHttpRequest', | ||||
|         'Accept-Language': 'zh-CN,zh-Hans;q=0.9', | ||||
|         'Accept-Encoding': 'gzip, deflate, br', | ||||
|         'Content-Type': 'application/x-www-form-urlencoded', | ||||
|         'Origin': 'https://lzkj-isv.isvjcloud.com', | ||||
|         'User-Agent': ua, | ||||
|         'Connection': 'keep-alive', | ||||
|         'Referer': activityUrl, | ||||
|         'Cookie': activityCookie | ||||
|     } | ||||
|     response = requests.request("POST", url, headers=headers, data=payload) | ||||
|     refresh_cookies(response) | ||||
|     res = response.json() | ||||
|     if res['result']: | ||||
|         hasAddCartSize = res['data']['hasAddCartSize'] | ||||
|         return hasAddCartSize | ||||
|     else: | ||||
|         print(f"⛈{res['errorMessage']}") | ||||
| 
 | ||||
| def getPrize(pin): | ||||
|     url = "https://lzkj-isv.isvjcloud.com/wxCollectionActivity/getPrize" | ||||
|     payload = f"activityId={activityId}&pin={quote_plus(pin)}" | ||||
|     headers = { | ||||
|         'Host': 'lzkj-isv.isvjcloud.com', | ||||
|         'Accept': 'application/json', | ||||
|         'X-Requested-With': 'XMLHttpRequest', | ||||
|         'Accept-Language': 'zh-CN,zh-Hans;q=0.9', | ||||
|         'Accept-Encoding': 'gzip, deflate, br', | ||||
|         'Content-Type': 'application/x-www-form-urlencoded', | ||||
|         'Origin': 'https://lzkj-isv.isvjcloud.com', | ||||
|         'User-Agent': ua, | ||||
|         'Connection': 'keep-alive', | ||||
|         'Referer': activityUrl, | ||||
|         'Cookie': f'IsvToken={token};{activityCookie}' | ||||
|     } | ||||
|     response = requests.request("POST", url, headers=headers, data=payload) | ||||
|     res = response.json() | ||||
|     if res['result']: | ||||
|         data = res['data'] | ||||
|         if data['drawOk']: | ||||
|             priceName = data['name'] | ||||
|             return priceName | ||||
|         else: | ||||
|             errorMessage = data['errorMessage'] | ||||
|             print(f"⛈{errorMessage}") | ||||
|             if "不足" in errorMessage: | ||||
|                 sys.exit() | ||||
|             return | ||||
|     else: | ||||
|         print(f"⛈{res['errorMessage']}") | ||||
|         if '奖品已发完' in res['errorMessage']: | ||||
|             sys.exit() | ||||
| 
 | ||||
| 
 | ||||
| if __name__ == '__main__': | ||||
|     r = redis_conn() | ||||
|     try: | ||||
|         cks = getCk | ||||
|         if not cks: | ||||
|             sys.exit() | ||||
|     except: | ||||
|         print("未获取到有效COOKIE,退出程序!") | ||||
|         sys.exit() | ||||
|     num = 0 | ||||
|     for cookie in cks[:runNums]: | ||||
|         num += 1 | ||||
|         if num % 5 == 0: | ||||
|             print("⏰等待3s,休息一下") | ||||
|             time.sleep(3) | ||||
|         global ua, activityCookie, token | ||||
|         ua = userAgent() | ||||
|         try: | ||||
|             pt_pin = re.compile(r'pt_pin=(.*?);').findall(cookie)[0] | ||||
|             pt_pin = unquote_plus(pt_pin) | ||||
|         except IndexError: | ||||
|             pt_pin = f'用户{num}' | ||||
|         print(f'\n******开始【京东账号{num}】{pt_pin} *********\n') | ||||
|         print(datetime.now()) | ||||
|         token = getToken(cookie, r) | ||||
|         if token is None: | ||||
|             print(f"⚠️获取Token失败!⏰等待2s") | ||||
|             time.sleep(2) | ||||
|             continue | ||||
|         time.sleep(0.2) | ||||
|         getAct = getActivity() | ||||
|         activityCookie = getAct[0] | ||||
|         activityType = getAct[1] | ||||
|         time.sleep(0.3) | ||||
|         getSystemConfigForNew(activityType) | ||||
|         time.sleep(0.2) | ||||
|         getSimAct = getSimpleActInfoVo() | ||||
|         venderId = getSimAct['venderId'] | ||||
|         time.sleep(0.2) | ||||
|         getPin = getMyPing(venderId) | ||||
|         if getPin is not None: | ||||
|             nickname = getPin[0] | ||||
|             secretPin = getPin[1] | ||||
|             time.sleep(0.3) | ||||
|             accessLogWithAD(venderId, secretPin, activityType) | ||||
|             time.sleep(0.2) | ||||
|             actCont = activityContent(secretPin) | ||||
|             # needCollectionSize, hasCollectionSize, needFollow, hasFollow, cpvos, drawOk, priceName, oneKeyAddCart | ||||
|             if not actCont: | ||||
|                 continue | ||||
|             needCollectionSize = actCont[0] | ||||
|             hasCollectionSize = actCont[1] | ||||
|             needFollow = actCont[2] | ||||
|             hasFollow = actCont[3] | ||||
|             cpvos = actCont[4] | ||||
|             drawOk = actCont[5] | ||||
|             priceName = actCont[6] | ||||
|             oneKeyAddCart = actCont[7] | ||||
|             if needCollectionSize <= hasCollectionSize: | ||||
|                 print("☃️已完成过加购任务,无法重复进行!") | ||||
|                 continue | ||||
|             else: | ||||
|                 skuIds = [covo['skuId'] for covo in cpvos if not covo['collection']] | ||||
|             time.sleep(0.2) | ||||
|             shopName = shopInfo() | ||||
|             if num == 1: | ||||
|                 print(f"✅开启{shopName}-加购活动,需关注加购{needCollectionSize}个商品") | ||||
|                 print(f"🎁奖品{priceName}\n") | ||||
|             time.sleep(0.2) | ||||
|             getInfo() | ||||
|             if needFollow: | ||||
|                 if not hasFollow: | ||||
|                     followShop(venderId, secretPin, activityType) | ||||
|             time.sleep(0.2) | ||||
|             addSkuNums = needCollectionSize - hasCollectionSize | ||||
|             if oneKeyAddCart == 1: | ||||
|                 hasAddCartSize = oneKeyAdd(skuIds, secretPin) | ||||
|                 if hasAddCartSize: | ||||
|                     if hasAddCartSize == addSkuNums: | ||||
|                         print(f"🛳成功一键加购{hasAddCartSize}个商品") | ||||
|             else: | ||||
|                 for productId in skuIds: | ||||
|                     if activityType == 6: | ||||
|                         hasAddCartSize = addCard(productId, secretPin) | ||||
|                     elif activityType == 5: | ||||
|                         hasAddCartSize = collection(productId, secretPin) | ||||
|                     time.sleep(0.2) | ||||
|                     if hasAddCartSize: | ||||
|                         if hasAddCartSize == addSkuNums: | ||||
|                             print(f"🛳成功加购{hasAddCartSize}个商品") | ||||
|                             break | ||||
|             time.sleep(0.1) | ||||
|             priceName = getPrize(secretPin) | ||||
|             if priceName: | ||||
|                 print(f"🎉获得{priceName}") | ||||
|             else: | ||||
|                 print(f"😭获得💨💨💨") | ||||
| 
 | ||||
|         time.sleep(3) | ||||
							
								
								
									
										579
									
								
								jd_wxCompleteInfo.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										579
									
								
								jd_wxCompleteInfo.py
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,579 @@ | ||||
| #!/usr/bin/env python3 | ||||
| # -*- coding: utf-8 -*- | ||||
| 
 | ||||
| """ | ||||
| File: jd_wxCompleteInfo.py(完善信息有礼-监控脚本) | ||||
| Author: HarbourJ | ||||
| Date: 2022/8/8 19:52 | ||||
| TG: https://t.me/HarbourToulu | ||||
| TgChat: https://t.me/HarbourSailing | ||||
| cron: 1 1 1 1 1 1 | ||||
| new Env('完善信息有礼-JK'); | ||||
| ActivityEntry: https://cjhy-isv.isvjcloud.com/wx/completeInfoActivity/view/activity?activityId=f3325e3375a14866xxxxxxxxxxxx&venderId=1000086 | ||||
|                变量 export jd_wxCompleteInfoId="f3325e3375a14866xxxxxxxxxxxx&1000086192"(活动id&venderId) | ||||
| """ | ||||
| 
 | ||||
| import time, requests, sys, re, os, json, random | ||||
| from datetime import datetime | ||||
| from urllib.parse import quote_plus, unquote_plus | ||||
| from functools import partial | ||||
| print = partial(print, flush=True) | ||||
| import warnings | ||||
| warnings.filterwarnings("ignore", category=DeprecationWarning) | ||||
| try: | ||||
|     from jd_sign import * | ||||
| except ImportError as e: | ||||
|     print(e) | ||||
|     if "No module" in str(e): | ||||
|         print("请先运行Faker库依赖一键安装脚本(jd_check_dependent.py),安装jd_sign.so依赖") | ||||
| try: | ||||
|     from jdCookie import get_cookies | ||||
|     getCk = get_cookies() | ||||
| except: | ||||
|     print("请先下载依赖脚本,\n下载链接: https://raw.githubusercontent.com/HarbourJ/HarbourToulu/main/jdCookie.py") | ||||
|     sys.exit(3) | ||||
| redis_url = os.environ.get("redis_url") if os.environ.get("redis_url") else "172.17.0.1" | ||||
| redis_port = os.environ.get("redis_port") if os.environ.get("redis_port") else "6379" | ||||
| redis_pwd = os.environ.get("redis_pwd") if os.environ.get("redis_pwd") else "" | ||||
| jd_wxCompleteInfoId = os.environ.get("jd_wxCompleteInfoId") if os.environ.get("jd_wxCompleteInfoId") else "" | ||||
| 
 | ||||
| if not jd_wxCompleteInfoId or "&" not in jd_wxCompleteInfoId: | ||||
|     print("⚠️未发现有效活动变量jd_wxCompleteInfoId,退出程序!") | ||||
|     sys.exit() | ||||
| activityId = jd_wxCompleteInfoId.split('&')[0] | ||||
| venderId = jd_wxCompleteInfoId.split('&')[1] | ||||
| 
 | ||||
| activityUrl = f"https://cjhy-isv.isvjcloud.com/wx/completeInfoActivity/view/activity?activityId={activityId}&venderId={venderId}" | ||||
| print(f"【🛳活动入口】{activityUrl}") | ||||
| 
 | ||||
| def redis_conn(): | ||||
|     try: | ||||
|         try: | ||||
|             import redis | ||||
|         except Exception as e: | ||||
|             print(e) | ||||
|             if "No module" in str(e): | ||||
|                 os.system("pip install redis") | ||||
|             import redis | ||||
|         try: | ||||
|             pool = redis.ConnectionPool(host=redis_url, port=redis_port, decode_responses=True, socket_connect_timeout=5, password=redis_pwd) | ||||
|             r = redis.Redis(connection_pool=pool) | ||||
|             r.get('conn_test') | ||||
|             print('✅redis连接成功') | ||||
|             return r | ||||
|         except: | ||||
|             print("⚠️redis连接异常") | ||||
|     except: | ||||
|         print("⚠️缺少redis依赖,请运行pip3 install redis") | ||||
|         sys.exit() | ||||
| 
 | ||||
| def getToken(ck, r=None): | ||||
|     host = f'{activityUrl.split("com/")[0]}com' | ||||
|     try: | ||||
|         # redis缓存Token 活动域名+pt_pin | ||||
|         pt_pin = unquote_plus(re.compile(r'pt_pin=(.*?);').findall(ck)[0]) | ||||
|     except: | ||||
|         # redis缓存Token 活动域名+ck前7位(获取pin失败) | ||||
|         pt_pin = ck[:15] | ||||
|     try: | ||||
|         if r is not None: | ||||
|             Token = r.get(f'{activityUrl.split("https://")[1].split("-")[0]}_{pt_pin}') | ||||
|             # print("Token过期时间", r.ttl(f'{activityUrl.split("https://")[1].split("-")[0]}_{pt_pin}')) | ||||
|             if Token is not None: | ||||
|                 print(f"♻️获取缓存Token") | ||||
|                 return Token | ||||
|             else: | ||||
|                 # print("🈳去设置Token缓存") | ||||
|                 s.headers = { | ||||
|                     'Connection': 'keep-alive', | ||||
|                     'Accept-Encoding': 'gzip, deflate, br', | ||||
|                     'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8', | ||||
|                     'User-Agent': '', | ||||
|                     'Cookie': ck, | ||||
|                     'Host': 'api.m.jd.com', | ||||
|                     'Referer': '', | ||||
|                     'Accept-Language': 'zh-Hans-CN;q=1 en-CN;q=0.9', | ||||
|                     'Accept': '*/*' | ||||
|                 } | ||||
|                 sign_txt = sign({"url": f"{host}", "id": ""}, 'isvObfuscator') | ||||
|                 # print(sign_txt) | ||||
|                 f = s.post('https://api.m.jd.com/client.action', verify=False, timeout=30) | ||||
|                 if f.status_code != 200: | ||||
|                     print(f.status_code) | ||||
|                     return | ||||
|                 else: | ||||
|                     if "参数异常" in f.text: | ||||
|                         return | ||||
|                 Token_new = f.json()['token'] | ||||
|                 # print(f"Token->: {Token_new}") | ||||
|                 if r.set(f'{activityUrl.split("https://")[1].split("-")[0]}_{pt_pin}', Token_new, ex=1800): | ||||
|                     print("✅Token缓存成功") | ||||
|                 else: | ||||
|                     print("❌Token缓存失败") | ||||
|                 return Token_new | ||||
|         else: | ||||
|             s.headers = { | ||||
|                 'Connection': 'keep-alive', | ||||
|                 'Accept-Encoding': 'gzip, deflate, br', | ||||
|                 'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8', | ||||
|                 'User-Agent': '', | ||||
|                 'Cookie': ck, | ||||
|                 'Host': 'api.m.jd.com', | ||||
|                 'Referer': '', | ||||
|                 'Accept-Language': 'zh-Hans-CN;q=1 en-CN;q=0.9', | ||||
|                 'Accept': '*/*' | ||||
|             } | ||||
|             sign_txt = sign({"url": f"{host}", "id": ""}, 'isvObfuscator') | ||||
|             # print(sign_txt) | ||||
|             f = s.post('https://api.m.jd.com/client.action', verify=False, timeout=30) | ||||
|             if f.status_code != 200: | ||||
|                 print(f.status_code) | ||||
|                 return | ||||
|             else: | ||||
|                 if "参数异常" in f.text: | ||||
|                     return | ||||
|             Token = f.json()['token'] | ||||
|             print(f"✅获取实时Token") | ||||
|             return Token | ||||
|     except: | ||||
|         return | ||||
| 
 | ||||
| def getJdTime(): | ||||
|     jdTime = int(round(time.time() * 1000)) | ||||
|     return jdTime | ||||
| 
 | ||||
| def randomString(e, flag=False): | ||||
|     t = "0123456789abcdef" | ||||
|     if flag: t = t.upper() | ||||
|     n = [random.choice(t) for _ in range(e)] | ||||
|     return ''.join(n) | ||||
| 
 | ||||
| def refresh_cookies(res): | ||||
|     if res.cookies: | ||||
|         cookies = res.cookies.get_dict() | ||||
|         set_cookie = [(set_cookie + "=" + cookies[set_cookie]) for set_cookie in cookies] | ||||
|         global activityCookie | ||||
|         activityCookieMid = [i for i in activityCookie.split(';') if i != ''] | ||||
|         for i in activityCookieMid: | ||||
|             for x in set_cookie: | ||||
|                 if i.split('=')[0] == x.split('=')[0]: | ||||
|                     if i.split('=')[1] != x.split('=')[1]: | ||||
|                         activityCookieMid.remove(i) | ||||
|         activityCookie = ''.join(sorted([(set_cookie + ";") for set_cookie in list(set(activityCookieMid + set_cookie))])) | ||||
| 
 | ||||
| def getActivity(): | ||||
|     url = activityUrl | ||||
|     headers = { | ||||
|         'Host': 'cjhy-isv.isvjcloud.com', | ||||
|         'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8', | ||||
|         'User-Agent': ua, | ||||
|         'Accept-Language': 'zh-CN,zh-Hans;q=0.9', | ||||
|         'Accept-Encoding': 'gzip, deflate, br', | ||||
|         'Connection': 'keep-alive' | ||||
|     } | ||||
|     response = requests.request("GET", url, headers=headers) | ||||
|     if response.status_code == 200: | ||||
|         if response.cookies: | ||||
|             cookies = response.cookies.get_dict() | ||||
|             set_cookies = [(set_cookie + "=" + cookies[set_cookie]) for set_cookie in cookies] | ||||
|             set_cookie = ''.join(sorted([(set_cookie + ";") for set_cookie in set_cookies])) | ||||
|         return set_cookie | ||||
|     else: | ||||
|         print(response.status_code) | ||||
|         print("⚠️疑似ip黑了") | ||||
|         sys.exit() | ||||
| 
 | ||||
| def getOpenStatus(): | ||||
|     url = "https://cjhy-isv.isvjcloud.com/assembleConfig/getOpenStatus" | ||||
|     payload = f'activityId={activityId}' | ||||
|     headers = { | ||||
|         'Host': 'cjhy-isv.isvjcloud.com', | ||||
|         'Accept': 'application/json', | ||||
|         'X-Requested-With': 'XMLHttpRequest', | ||||
|         'Accept-Language': 'zh-CN,zh-Hans;q=0.9', | ||||
|         'Accept-Encoding': 'gzip, deflate, br', | ||||
|         'Content-Type': 'application/x-www-form-urlencoded', | ||||
|         'Origin': 'https://cjhy-isv.isvjcloud.com', | ||||
|         'User-Agent': ua, | ||||
|         'Connection': 'keep-alive', | ||||
|         'Referer': activityUrl, | ||||
|         'Cookie': activityCookie | ||||
|     } | ||||
|     response = requests.request("POST", url, headers=headers, data=payload) | ||||
| 
 | ||||
| def getSystemConfig(): | ||||
|     url = "https://cjhy-isv.isvjcloud.com/wxCommonInfo/getSystemConfig" | ||||
|     payload = f'activityId={activityId}&activityType=' | ||||
|     headers = { | ||||
|         'Host': 'cjhy-isv.isvjcloud.com', | ||||
|         'Accept': 'application/json', | ||||
|         'X-Requested-With': 'XMLHttpRequest', | ||||
|         'Accept-Language': 'zh-CN,zh-Hans;q=0.9', | ||||
|         'Accept-Encoding': 'gzip, deflate, br', | ||||
|         'Content-Type': 'application/x-www-form-urlencoded', | ||||
|         'Origin': 'https://cjhy-isv.isvjcloud.com', | ||||
|         'User-Agent': ua, | ||||
|         'Connection': 'keep-alive', | ||||
|         'Referer': activityUrl, | ||||
|         'Cookie': activityCookie | ||||
|     } | ||||
|     response = requests.request("POST", url, headers=headers, data=payload) | ||||
|     refresh_cookies(response) | ||||
| 
 | ||||
| def getSimpleActInfoVo(): | ||||
|     url = "https://cjhy-isv.isvjcloud.com/customer/getSimpleActInfoVo" | ||||
|     payload = f"activityId={activityId}" | ||||
|     headers = { | ||||
|         'Host': 'cjhy-isv.isvjcloud.com', | ||||
|         'Accept': 'application/json', | ||||
|         'X-Requested-With': 'XMLHttpRequest', | ||||
|         'Accept-Language': 'zh-CN,zh-Hans;q=0.9', | ||||
|         'Accept-Encoding': 'gzip, deflate, br', | ||||
|         'Content-Type': 'application/x-www-form-urlencoded', | ||||
|         'Origin': 'https://cjhy-isv.isvjcloud.com', | ||||
|         'User-Agent': ua, | ||||
|         'Connection': 'keep-alive', | ||||
|         'Referer': activityUrl, | ||||
|         'Cookie': activityCookie | ||||
|     } | ||||
|     response = requests.request("POST", url, headers=headers, data=payload) | ||||
|     refresh_cookies(response) | ||||
|     res = response.json() | ||||
|     if res['result']: | ||||
|         return res['data'] | ||||
|     else: | ||||
|         print(res['errorMessage']) | ||||
| 
 | ||||
| def getMyPing(venderId): | ||||
|     url = "https://cjhy-isv.isvjcloud.com/customer/getMyPing" | ||||
|     payload = f"userId={venderId}&token={token}&fromType=APP&riskType=1" | ||||
|     headers = { | ||||
|         'Host': 'cjhy-isv.isvjcloud.com', | ||||
|         'Accept': 'application/json', | ||||
|         'X-Requested-With': 'XMLHttpRequest', | ||||
|         'Accept-Language': 'zh-CN,zh-Hans;q=0.9', | ||||
|         'Accept-Encoding': 'gzip, deflate, br', | ||||
|         'Content-Type': 'application/x-www-form-urlencoded', | ||||
|         'Origin': 'https://cjhy-isv.isvjcloud.com', | ||||
|         'User-Agent': ua, | ||||
|         'Connection': 'keep-alive', | ||||
|         'Referer': activityUrl, | ||||
|         'Cookie': activityCookie | ||||
|     } | ||||
|     response = requests.request("POST", url, headers=headers, data=payload) | ||||
|     if response.status_code == 200: | ||||
|         refresh_cookies(response) | ||||
|         res = response.json() | ||||
|         if res['result']: | ||||
|             return res['data']['nickname'], res['data']['secretPin'] | ||||
|         else: | ||||
|             print(f"⚠️{res['errorMessage']}") | ||||
|     else: | ||||
|         print(response.status_code) | ||||
|         print("⚠️疑似ip黑了") | ||||
|         sys.exit() | ||||
| 
 | ||||
| def _selectById(venderId): | ||||
|     url = "https://cjhy-isv.isvjcloud.com/completeInfoActivity/selectById" | ||||
|     body = f"activityId={activityId}&venderId={venderId}" | ||||
|     headers = { | ||||
|         'Host': 'cjhy-isv.isvjcloud.com', | ||||
|         'Accept': 'application/json', | ||||
|         'X-Requested-With': 'XMLHttpRequest', | ||||
|         'Accept-Language': 'zh-CN,zh-Hans;q=0.9', | ||||
|         'Accept-Encoding': 'gzip, deflate, br', | ||||
|         'Content-Type': 'application/x-www-form-urlencoded', | ||||
|         'Origin': 'https://cjhy-isv.isvjcloud.com', | ||||
|         'User-Agent': ua, | ||||
|         'Connection': 'keep-alive', | ||||
|         'Referer': activityUrl, | ||||
|         'Cookie': activityCookie | ||||
|     } | ||||
|     response = requests.request("POST", url, headers=headers, data=body) | ||||
|     res = response.json() | ||||
|     if res['result']: | ||||
|         saveInfo = "" | ||||
|         data = res['data'] | ||||
|         chooseName = data['chooseName'] | ||||
|         choosePhone = data['choosePhone'] | ||||
|         chooseBirth = data['chooseBirth'] | ||||
|         chooseWeixin = data['chooseWeixin'] | ||||
|         chooseAddress = data['chooseAddress'] | ||||
|         chooseQQ = data['chooseQQ'] | ||||
|         chooseEmail = data['chooseEmail'] | ||||
|         chooseGender = data['chooseGender'] | ||||
|         chooseProfessional = data['chooseProfessional'] | ||||
|         customJson = data['customJson'] | ||||
|         phone = get_mobile() | ||||
|         if chooseName == 'y': | ||||
|             name = quote_plus(f"{random.choice(['A','B','C','D','E','F','G','H'])}贤笙") | ||||
|             saveInfo += f"name={name}&" | ||||
|         if choosePhone == 'y': | ||||
|             saveInfo += f"phone={phone}&" | ||||
|         if chooseBirth == 'y': | ||||
|             birthDay = "2000-01-01" | ||||
|             saveInfo += f"birthDay={birthDay}&" | ||||
|         if chooseWeixin == 'y': | ||||
|             weiXin = phone | ||||
|             saveInfo += f"weiXin={weiXin}&" | ||||
|         if chooseEmail == 'y': | ||||
|             email = quote_plus(f"{phone}@163.com") | ||||
|             saveInfo += f"email={email}&" | ||||
|         if chooseGender == 'y': | ||||
|             gender = quote_plus("男") | ||||
|             saveInfo += f"gender={gender}&" | ||||
|         if chooseProfessional == 'y': | ||||
|             professional = "Engineer" | ||||
|             saveInfo += f"professional={professional}&" | ||||
|         if chooseQQ == 'y': | ||||
|             qq = phone | ||||
|             saveInfo += f"{qq}&" | ||||
|         if chooseAddress == 'y': | ||||
|             province = quote_plus("北京市") | ||||
|             city = quote_plus("东城区") | ||||
|             address = quote_plus("北京大学城北门") | ||||
|             saveInfo += f"province={province}&city={city}&address={address}&" | ||||
|         if customJson != "[]": | ||||
|             customContent = "%5B%2222%22%5D" | ||||
|             saveInfo += f"customContent={customContent}&" | ||||
|         return saveInfo | ||||
|     else: | ||||
|         print(res['errorMessage']) | ||||
| 
 | ||||
| def getOpenCardInfo(venderId, pin, activityType): | ||||
|     url = "https://cjhy-isv.isvjcloud.com/mc/new/brandCard/common/shopAndBrand/getOpenCardInfo" | ||||
|     body = f"venderId={venderId}&buyerPin={pin}&activityType={activityType}" | ||||
|     headers = { | ||||
|         'Host': 'cjhy-isv.isvjcloud.com', | ||||
|         'Accept': 'application/json', | ||||
|         'X-Requested-With': 'XMLHttpRequest', | ||||
|         'Accept-Language': 'zh-CN,zh-Hans;q=0.9', | ||||
|         'Accept-Encoding': 'gzip, deflate, br', | ||||
|         'Content-Type': 'application/x-www-form-urlencoded', | ||||
|         'Origin': 'https://cjhy-isv.isvjcloud.com', | ||||
|         'User-Agent': ua, | ||||
|         'Connection': 'keep-alive', | ||||
|         'Referer': activityUrl, | ||||
|         'Cookie': activityCookie | ||||
|     } | ||||
|     response = requests.request("POST", url, headers=headers, data=body) | ||||
|     res = response.json() | ||||
|     if res['result']: | ||||
|         return res['data'] | ||||
|     else: | ||||
|         print(res['errorMessage']) | ||||
| 
 | ||||
| def getShopInfoVO(venderId): | ||||
|     url = "https://cjhy-isv.isvjcloud.com/wxActionCommon/getShopInfoVO" | ||||
|     payload = f"userId={venderId}" | ||||
|     headers = { | ||||
|         'Host': 'cjhy-isv.isvjcloud.com', | ||||
|         'Accept': 'application/json', | ||||
|         'X-Requested-With': 'XMLHttpRequest', | ||||
|         'Accept-Language': 'zh-CN,zh-Hans;q=0.9', | ||||
|         'Accept-Encoding': 'gzip, deflate, br', | ||||
|         'Content-Type': 'application/x-www-form-urlencoded', | ||||
|         'Origin': 'https://cjhy-isv.isvjcloud.com', | ||||
|         'User-Agent': ua, | ||||
|         'Connection': 'keep-alive', | ||||
|         'Referer': activityUrl, | ||||
|         'Cookie': activityCookie | ||||
|     } | ||||
|     response = requests.request("POST", url, headers=headers, data=payload) | ||||
|     res = response.json() | ||||
|     if res['result']: | ||||
|         return res['data'] | ||||
|     else: | ||||
|         print(res['errorMessage']) | ||||
| 
 | ||||
| def accessLog(venderId, pin, activityType): | ||||
|     url = "https://cjhy-isv.isvjcloud.com/common/accessLog" | ||||
|     payload = f"venderId={venderId}&code={activityType}&pin={quote_plus(pin)}&activityId={activityId}&pageUrl={quote_plus(activityUrl)}&subType=" | ||||
|     headers = { | ||||
|         'Host': 'cjhy-isv.isvjcloud.com', | ||||
|         'Accept': 'application/json', | ||||
|         'X-Requested-With': 'XMLHttpRequest', | ||||
|         'Accept-Language': 'zh-CN,zh-Hans;q=0.9', | ||||
|         'Accept-Encoding': 'gzip, deflate, br', | ||||
|         'Content-Type': 'application/x-www-form-urlencoded', | ||||
|         'Origin': 'https://cjhy-isv.isvjcloud.com', | ||||
|         'User-Agent': ua, | ||||
|         'Connection': 'keep-alive', | ||||
|         'Referer': activityUrl, | ||||
|         'Cookie': activityCookie | ||||
|     } | ||||
|     requests.request("POST", url, headers=headers, data=payload) | ||||
| 
 | ||||
| def listDrawContent(activityType): | ||||
|     url = "https://cjhy-isv.isvjcloud.com/drawContent/listDrawContent" | ||||
|     body = f"activityId={activityId}&type={activityType}" | ||||
|     headers = { | ||||
|         'Host': 'cjhy-isv.isvjcloud.com', | ||||
|         'Accept': 'application/json', | ||||
|         'X-Requested-With': 'XMLHttpRequest', | ||||
|         'Accept-Language': 'zh-CN,zh-Hans;q=0.9', | ||||
|         'Accept-Encoding': 'gzip, deflate, br', | ||||
|         'Content-Type': 'application/x-www-form-urlencoded', | ||||
|         'Origin': 'https://cjhy-isv.isvjcloud.com', | ||||
|         'User-Agent': ua, | ||||
|         'Connection': 'keep-alive', | ||||
|         'Referer': activityUrl, | ||||
|         'Cookie': activityCookie | ||||
|     } | ||||
|     response = requests.request("POST", url, headers=headers, data=body) | ||||
|     res = response.json() | ||||
|     if res['result']: | ||||
|         return res['data'] | ||||
|     else: | ||||
|         # print(res['errorMessage']) | ||||
|         if "暂未填写" in res['errorMessage']: | ||||
|             print("📝现在去完善信息") | ||||
| 
 | ||||
| def selectById(pin, venderId): | ||||
|     url = "https://cjhy-isv.isvjcloud.com/wx/completeInfoActivity/selectById" | ||||
|     body = f"activityId={activityId}&pin={quote_plus(pin)}&venderId={venderId}" | ||||
|     headers = { | ||||
|         'Host': 'cjhy-isv.isvjcloud.com', | ||||
|         'Accept': 'application/json', | ||||
|         'X-Requested-With': 'XMLHttpRequest', | ||||
|         'Accept-Language': 'zh-CN,zh-Hans;q=0.9', | ||||
|         'Accept-Encoding': 'gzip, deflate, br', | ||||
|         'Content-Type': 'application/x-www-form-urlencoded', | ||||
|         'Origin': 'https://cjhy-isv.isvjcloud.com', | ||||
|         'User-Agent': ua, | ||||
|         'Connection': 'keep-alive', | ||||
|         'Referer': activityUrl, | ||||
|         'Cookie': activityCookie | ||||
|     } | ||||
|     response = requests.request("POST", url, headers=headers, data=body) | ||||
|     refresh_cookies(response) | ||||
|     res = response.json() | ||||
|     if res['result']: | ||||
|         return res['data'] | ||||
|     else: | ||||
|         # print(res['errorMessage']) | ||||
|         if "暂未填写" in res['errorMessage']: | ||||
|             print("📝现在去完善会员信息") | ||||
| 
 | ||||
| def getInfo(): | ||||
|     url = f"https://cjhy-isv.isvjcloud.com/miniProgramShareInfo/getInfo?activityId={activityId}" | ||||
|     headers = { | ||||
|         'Host': 'cjhy-isv.isvjcloud.com', | ||||
|         'Accept-Encoding': 'gzip, deflate, br', | ||||
|         'Connection': 'keep-alive', | ||||
|         'Accept': 'application/json', | ||||
|         'User-Agent': ua, | ||||
|         'Referer': activityUrl, | ||||
|         'Accept-Language': 'zh-CN,zh-Hans;q=0.9', | ||||
|         'X-Requested-With': 'XMLHttpRequest', | ||||
|         'Cookie': activityCookie, | ||||
|     } | ||||
|     requests.request("GET", url, headers=headers) | ||||
| 
 | ||||
| def get_mobile(): | ||||
|     mobiles = ['130', '131', '132', '133', '134'] | ||||
|     number = str(int(time.time()))[2:] | ||||
|     mobile = random.choice(mobiles)+number | ||||
|     return mobile | ||||
| 
 | ||||
| def save(saveInfo, venderId, pin, drawInfoId): | ||||
|     url = "https://cjhy-isv.isvjcloud.com/wx/completeInfoActivity/save" | ||||
|     body = f"{saveInfo}drawInfoId={drawInfoId}&activityId={activityId}&venderId={venderId}&pin={quote_plus(pin)}&vcode=&token={token}&fromType=APP" | ||||
|     headers = { | ||||
|         'Host': 'cjhy-isv.isvjcloud.com', | ||||
|         'Accept': 'application/json', | ||||
|         'X-Requested-With': 'XMLHttpRequest', | ||||
|         'Accept-Language': 'zh-CN,zh-Hans;q=0.9', | ||||
|         'Accept-Encoding': 'gzip, deflate, br', | ||||
|         'Content-Type': 'application/x-www-form-urlencoded', | ||||
|         'Origin': 'https://cjhy-isv.isvjcloud.com', | ||||
|         'User-Agent': ua, | ||||
|         'Connection': 'keep-alive', | ||||
|         'Referer': activityUrl, | ||||
|         'Cookie': activityCookie | ||||
|     } | ||||
|     response = requests.request("POST", url, headers=headers, data=body) | ||||
|     res = response.json() | ||||
|     if res['result']: | ||||
|         return res['data'] | ||||
|     else: | ||||
|         print(res['errorMessage']) | ||||
| 
 | ||||
| 
 | ||||
| if __name__ == '__main__': | ||||
|     r = redis_conn() | ||||
|     try: | ||||
|         cks = getCk | ||||
|         if not cks: | ||||
|             sys.exit() | ||||
|     except: | ||||
|         print("未获取到有效COOKIE,退出程序!") | ||||
|         sys.exit() | ||||
|     num = 0 | ||||
|     for cookie in cks[:]: | ||||
|         num += 1 | ||||
|         if num % 9 == 0: | ||||
|             print("⏰等待5s,休息一下") | ||||
|             time.sleep(5) | ||||
|         global ua, activityCookie, token | ||||
|         ua = userAgent() | ||||
|         try: | ||||
|             pt_pin = re.compile(r'pt_pin=(.*?);').findall(cookie)[0] | ||||
|             pt_pin = unquote_plus(pt_pin) | ||||
|         except IndexError: | ||||
|             pt_pin = f'用户{num}' | ||||
|         print(f'\n******开始【京东账号{num}】{pt_pin} *********\n') | ||||
|         print(datetime.now()) | ||||
|         token = getToken(cookie, r) | ||||
|         if token is None: | ||||
|             print(f"⚠️获取Token失败!⏰等待2s") | ||||
|             time.sleep(2) | ||||
|             continue | ||||
|         time.sleep(0.2) | ||||
|         activityCookie = getActivity() | ||||
|         time.sleep(0.3) | ||||
|         getOpenStatus() | ||||
|         time.sleep(0.1) | ||||
|         getSimAct = getSimpleActInfoVo() | ||||
|         venderId = getSimAct['venderId'] | ||||
|         activityType = getSimAct['activityType'] | ||||
|         time.sleep(0.2) | ||||
|         getPin = getMyPing(venderId) | ||||
|         if getPin: | ||||
|             nickname = getPin[0] | ||||
|             secretPin = getPin[1] | ||||
|             time.sleep(0.2) | ||||
|             getOC = getOpenCardInfo(venderId, secretPin, activityType) | ||||
|             time.sleep(0.1) | ||||
|             if getOC['openedCard']: | ||||
|                 getShopInfo = getShopInfoVO(venderId) | ||||
|                 shopName = getShopInfo['shopName'] | ||||
|                 print(f"✅开启{shopName} 店铺完善会员信息有礼") | ||||
|                 accessLog(venderId, secretPin, activityType) | ||||
|                 time.sleep(0.2) | ||||
|                 saveInfo = _selectById(venderId) | ||||
|                 time.sleep(0.2) | ||||
|                 selectBI = selectById(secretPin, venderId) | ||||
|                 if selectBI: | ||||
|                     print(f"💨{nickname} 已经完善过店铺信息") | ||||
|                     continue | ||||
|                 else: | ||||
|                     time.sleep(0.2) | ||||
|                     listDraw = listDrawContent(activityType) | ||||
|                     drawInfoId = listDraw[0]['drawInfoId'] | ||||
|                     time.sleep(0.2) | ||||
|                     getInfo() | ||||
|                     time.sleep(0.1) | ||||
|                     sv = save(saveInfo, venderId, secretPin, drawInfoId) | ||||
|                     if sv: | ||||
|                         drawInfo = sv['drawInfo']['name'] | ||||
|                         if drawInfo: | ||||
|                             print(f"🎉🎉🎉{nickname} 成功领取 {drawInfo}") | ||||
|                         else: | ||||
|                             print(f"⛈⛈⛈{nickname} 领取完善有礼奖励失败,请重试~") | ||||
|                     else: | ||||
|                         print(f"💨{nickname} 已经领过完善有礼奖励~") | ||||
|             else: | ||||
|                 print(f"⛈{nickname} 非店铺会员无法完善信息!") | ||||
|                 continue | ||||
|         time.sleep(2.5) | ||||
							
								
								
									
										107
									
								
								jd_wxShopGift.py
									
									
									
									
									
								
							
							
						
						
									
										107
									
								
								jd_wxShopGift.py
									
									
									
									
									
								
							| @ -2,39 +2,38 @@ | ||||
| # -*- coding: utf-8 -*- | ||||
| 
 | ||||
| """ | ||||
| File: jd_wxShopGift.py(店铺特效关注有礼) | ||||
| File: jd_wxShopGift.py(店铺特效关注有礼-监控脚本) | ||||
| Author: HarbourJ | ||||
| Date: 2022/8/8 19:52 | ||||
| TG: https://t.me/HarbourToulu | ||||
| TgChat: https://t.me/HarbourSailing | ||||
| cron: 1 1 1 1 1 1 | ||||
| new Env('店铺特效关注有礼'); | ||||
| new Env('店铺特效关注有礼-JK'); | ||||
| ActivityEntry: https://lzkj-isv.isvjcloud.com/wxShopGift/activity?activityId=971e85d5dfd445e1acfc63bafffb8ecc | ||||
|                变量 export jd_wxShopGiftId="971e85d5dfd445e1axxxxxxxxxxxx" | ||||
| """ | ||||
| 
 | ||||
| import time | ||||
| import requests | ||||
| import sys | ||||
| import re | ||||
| import os | ||||
| import time, requests, sys, re, os, json, random | ||||
| from datetime import datetime | ||||
| import json | ||||
| import random | ||||
| from urllib.parse import quote_plus, unquote_plus | ||||
| from functools import partial | ||||
| print = partial(print, flush=True) | ||||
| import warnings | ||||
| warnings.filterwarnings("ignore", category=DeprecationWarning) | ||||
| 
 | ||||
| from jd_sign import * | ||||
| try: | ||||
|     from jd_sign import * | ||||
| except ImportError as e: | ||||
|     print(e) | ||||
|     if "No module" in str(e): | ||||
|         print("请先运行Faker库依赖一键安装脚本(jd_check_dependent.py),安装jd_sign.so依赖") | ||||
| try: | ||||
|     from jdCookie import get_cookies | ||||
|     getCk = get_cookies() | ||||
| except: | ||||
|     print("请先下载依赖脚本,\n下载链接: https://raw.githubusercontent.com/shufflewzc/faker2/main/jdCookie.py") | ||||
|     print("请先下载依赖脚本,\n下载链接: https://raw.githubusercontent.com/HarbourJ/HarbourToulu/main/jdCookie.py") | ||||
|     sys.exit(3) | ||||
| redis_url = os.environ.get("redis_url") if os.environ.get("redis_url") else "172.17.0.1" | ||||
| redis_port = os.environ.get("redis_port") if os.environ.get("redis_port") else "6379" | ||||
| redis_pwd = os.environ.get("redis_pwd") if os.environ.get("redis_pwd") else "" | ||||
| activityId = os.environ.get("jd_wxShopGiftId") if os.environ.get("jd_wxShopGiftId") else "" | ||||
| 
 | ||||
| @ -47,7 +46,7 @@ def redis_conn(): | ||||
|     try: | ||||
|         import redis | ||||
|         try: | ||||
|             pool = redis.ConnectionPool(host=redis_url, port=6379, decode_responses=True, socket_connect_timeout=5, password=redis_pwd) | ||||
|             pool = redis.ConnectionPool(host=redis_url, port=redis_port, decode_responses=True, socket_connect_timeout=5, password=redis_pwd) | ||||
|             r = redis.Redis(connection_pool=pool) | ||||
|             r.get('conn_test') | ||||
|             print('✅redis连接成功') | ||||
| @ -65,16 +64,44 @@ def getToken(ck, r=None): | ||||
|         pt_pin = unquote_plus(re.compile(r'pt_pin=(.*?);').findall(ck)[0]) | ||||
|     except: | ||||
|         # redis缓存Token 活动域名+ck前7位(获取pin失败) | ||||
|         pt_pin = ck[:8] | ||||
|     if r is not None: | ||||
|         Token = r.get(f'{activityUrl.split("https://")[1].split("-")[0]}_{pt_pin}') | ||||
|         # print("Token过期时间", r.ttl(f'{activityUrl.split("https://")[1].split("-")[0]}_{pt_pin}')) | ||||
|         if Token is not None: | ||||
|             # print(f"♻️获取缓存Token->: {Token}") | ||||
|             print(f"♻️获取缓存Token") | ||||
|             return Token | ||||
|         pt_pin = ck[:15] | ||||
|     try: | ||||
|         if r is not None: | ||||
|             Token = r.get(f'{activityUrl.split("https://")[1].split("-")[0]}_{pt_pin}') | ||||
|             # print("Token过期时间", r.ttl(f'{activityUrl.split("https://")[1].split("-")[0]}_{pt_pin}')) | ||||
|             if Token is not None: | ||||
|                 print(f"♻️获取缓存Token") | ||||
|                 return Token | ||||
|             else: | ||||
|                 # print("🈳去设置Token缓存") | ||||
|                 s.headers = { | ||||
|                     'Connection': 'keep-alive', | ||||
|                     'Accept-Encoding': 'gzip, deflate, br', | ||||
|                     'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8', | ||||
|                     'User-Agent': '', | ||||
|                     'Cookie': ck, | ||||
|                     'Host': 'api.m.jd.com', | ||||
|                     'Referer': '', | ||||
|                     'Accept-Language': 'zh-Hans-CN;q=1 en-CN;q=0.9', | ||||
|                     'Accept': '*/*' | ||||
|                 } | ||||
|                 sign_txt = sign({"url": f"{host}", "id": ""}, 'isvObfuscator') | ||||
|                 # print(sign_txt) | ||||
|                 f = s.post('https://api.m.jd.com/client.action', verify=False, timeout=30) | ||||
|                 if f.status_code != 200: | ||||
|                     print(f.status_code) | ||||
|                     return | ||||
|                 else: | ||||
|                     if "参数异常" in f.text: | ||||
|                         return | ||||
|                 Token_new = f.json()['token'] | ||||
|                 # print(f"Token->: {Token_new}") | ||||
|                 if r.set(f'{activityUrl.split("https://")[1].split("-")[0]}_{pt_pin}', Token_new, ex=1800): | ||||
|                     print("✅Token缓存成功") | ||||
|                 else: | ||||
|                     print("❌Token缓存失败") | ||||
|                 return Token_new | ||||
|         else: | ||||
|             print("🈳去设置Token缓存") | ||||
|             s.headers = { | ||||
|                 'Connection': 'keep-alive', | ||||
|                 'Accept-Encoding': 'gzip, deflate, br', | ||||
| @ -95,37 +122,11 @@ def getToken(ck, r=None): | ||||
|             else: | ||||
|                 if "参数异常" in f.text: | ||||
|                     return | ||||
|             Token_new = f.json()['token'] | ||||
|             # print(f"Token->: {Token_new}") | ||||
|             if r.set(f'{activityUrl.split("https://")[1].split("-")[0]}_{pt_pin}', Token_new, ex=1800): | ||||
|                 print("✅Token缓存设置成功") | ||||
|             else: | ||||
|                 print("❌Token缓存设置失败") | ||||
|             return Token_new | ||||
|     else: | ||||
|         s.headers = { | ||||
|             'Connection': 'keep-alive', | ||||
|             'Accept-Encoding': 'gzip, deflate, br', | ||||
|             'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8', | ||||
|             'User-Agent': '', | ||||
|             'Cookie': ck, | ||||
|             'Host': 'api.m.jd.com', | ||||
|             'Referer': '', | ||||
|             'Accept-Language': 'zh-Hans-CN;q=1 en-CN;q=0.9', | ||||
|             'Accept': '*/*' | ||||
|         } | ||||
|         sign_txt = sign({"url": f"{host}", "id": ""}, 'isvObfuscator') | ||||
|         # print(sign_txt) | ||||
|         f = s.post('https://api.m.jd.com/client.action', verify=False, timeout=30) | ||||
|         if f.status_code != 200: | ||||
|             print(f.status_code) | ||||
|             return | ||||
|         else: | ||||
|             if "参数异常" in f.text: | ||||
|                 return | ||||
|         Token = f.json()['token'] | ||||
|         print(f"Token->: {Token}") | ||||
|         return Token | ||||
|             Token = f.json()['token'] | ||||
|             print(f"✅获取实时Token") | ||||
|             return Token | ||||
|     except: | ||||
|         return | ||||
| 
 | ||||
| def getJdTime(): | ||||
|     jdTime = int(round(time.time() * 1000)) | ||||
|  | ||||
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							
		Loading…
	
		Reference in New Issue
	
	Block a user
	 Faker
						Faker