队列获取任务
redis = {
"nb_task_queue":[...]
}
conn = ...
conn.lpush(..)
data = conn.rpop() # 如果有,取走,如果没有就是空
data = conn.brpop() # 如果有,取走,如果没有,等待
data = conn.brpop(timeout=30) # 如果有,取走,如果没有,最多等待30
while True:
data = conn.brpop(timeout=30)
if not data:
continue
数据库更新订单状态
import pymysql
conn = pymysql.connect(host='127.0.0.1', port=3306, user='root', passwd='123', db='t1')
cursor = conn.cursor()
# 插入、更新、删除
cursor.execute("update xxxxx set status = 2 where id=%s and name=%s", ["123456","admin"])
cursor.execute("update xxxxx set status = 2 where id=%(n1)s and name=%(n2)s", {"n1":"xxxx","n2":"xxx"})
conn.commit()
# 读取
cursor.execute("select * from xxx where id=9")
data = cursor.fetchone()
data = cursor.fetchall()
cursor.close()
conn.close()
- 简单封装
class Connect(object):
def __init__(self):
self.conn = None
self.cursor = None
def __enter__(self):
self.conn = conn = pymysql.connect(**settings.MYSQL_CONN_PARAMS)
self.cursor = conn.cursor(pymysql.cursors.DictCursor)
return self
def __exit__(self, exc_type, exc_val, exc_tb):
self.cursor.close()
self.conn.close()
def exec(self, sql, **kwargs):
self.cursor.execute(sql, kwargs)
self.conn.commit()
def fetch_one(self, sql, **kwargs):
self.cursor.execute(sql, kwargs)
result = self.cursor.fetchone()
return result
def fetch_all(self, sql, **kwargs):
self.cursor.execute(sql, kwargs)
result = self.cursor.fetchall()
return result
with Connect() as f1:
f1.exec("update xxxxx set status = 2 where id=%(n1)s", n1=99)
f1.exec("update xxxxx set status = 2 where id=%(n1)s", **{"n1":99})
f1.exec("update xxxxx set status = 2 where id=5")
f1.exec("update xxxxx set status = 2 where id=5")
f1.fetch_all("select * from tb")
x视频逆向
简单分析
ctime: 2023-01-03 18:53:42
ua: mozilla/5.0 (macintosh; intel mac os x 10_15_7) applewebkit/537.36 (khtml, like gecko) chrome/108.0.0.0 safari/537.36
hh_ua: mozilla/5.0 (macintosh; intel mac os x 10_15_7) applewebkit/537.36 (khtml, like gecko) chrome/108.0.0.0 safari/537.36
platform: 4330701
guid: lcg445zy_bpb904sr25b [需逆向]
Pwd: 1698957057
version: wc-1.25.0
url: https://w.yangshipin.cn/video?type=0&vid=g0000648jiz
hh_ref: https://w.yangshipin.cn/video?type=0&vid=g0000648jiz
vid: g0000648jiz
isfocustab: 1
isvisible: 1
idx: 0
val: 1130
pid: lcg447u7_lkfdu0waiq [需逆向]
bi: 0
bt: 0
defn: hd
vurl: https://mp4playali-cdn.ysp.cctv.cn/g00... [需逆向]
step: 6
val1: 1
val2: 1
fact1:
fact2:
fact3:
fact4:
fact5:
脚本
import time
import json
import datetime
import random
import binascii
import ctypes
from urllib.parse import urlencode, urlparse, parse_qs
from concurrent.futures import ThreadPoolExecutor
import execjs
import requests
from Crypto.Cipher import AES
body = """
function createGuid(){
var e = (new Date).getTime().toString(36);
var r = Math.random().toString(36).replace(/^0./, "");
return "".concat(e, "_").concat(r);
}
function createQn(Vn){
var Yn = 0;
var Le = -5516;
var qn;
for (var Ur = 0; Ur < Vn["length"]; Ur++){
Qn = Vn["charCodeAt"](Ur);
Yn = (Yn << Le + 1360 + 9081 - 4920) - Yn + Qn;
Yn &= Yn;
qn = Yn;
}
return qn;
}
"""
JS = execjs.compile(body)
def aes_encrypt(text):
"""
AES加密
"""
# "4E2918885FD98109869D14E0231A0BF4"
# "16B17E519DDD0CE5B79D7A63A4DD801C"
key = binascii.a2b_hex('4E2918885FD98109869D14E0231A0BF4')
iv = binascii.a2b_hex('16B17E519DDD0CE5B79D7A63A4DD801C')
pad = 16 - len(text) % 16
text = text + pad * chr(pad)
text = text.encode()
cipher = AES.new(key, AES.MODE_CBC, iv)
encrypt_bytes = cipher.encrypt(text)
return binascii.b2a_hex(encrypt_bytes).decode()
def create_ckey(vid, ctime, app_ver, platform, guid):
ending = "https://w.yangshipin.cn/|mozilla/5.0 (macintosh; ||Mozilla|Netscape|MacIntel|"
data_list = ["", vid, ctime, "mg3c3b04ba", app_ver, guid, platform, ending]
data_string = "|".join(data_list)
qn = JS.call('createQn', data_string)
encrypt_string = "|{}{}".format(qn, data_string)
ckey = "--01" + aes_encrypt(encrypt_string).upper()
return ckey
def get_video_info(vid, ctime, app_ver, platform, flow_id, guid, ckey):
params = {
"callback": "jsonp1",
"guid": guid,
"platform": platform,
"vid": vid,
"defn": "hd",
"charge": "0",
"defaultfmt": "auto",
"otype": "json",
"defnpayver": "1",
"appVer": app_ver,
"sphttps": "1",
"sphls": "1",
"spwm": "4",
"dtype": "3",
"defsrc": "2",
"encryptVer": "8.1",
"sdtfrom": platform,
"cKey": ckey,
"panoramic": "false",
"flowid": flow_id
}
headers = {
'user-agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/102.0.0.0 Safari/537.36',
'referer': 'https://m.yangshipin.cn/',
}
res = requests.get(
url="https://playvv.yangshipin.cn/playvinfo",
params=params,
headers=headers,
cookies={
"guid": guid
}
)
res.close()
text = res.text.strip("jsonp1")[1:-1]
info_dict = json.loads(text)
return info_dict
def play(platform, guid, video_url, vid, pid, vurl):
data = {
"ctime": datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S"),
"ua": "mozilla/5.0 (macintosh; intel mac os x 10_15_7) applewebkit/537.36 (khtml, like gecko) chrome/102.0.0.0 safari/537.36",
"hh_ua": "mozilla/5.0 (macintosh; intel mac os x 10_15_7) applewebkit/537.36 (khtml, like gecko) chrome/102.0.0.0 safari/537.36",
"platform": platform,
"guid": guid,
"Pwd": "1698957057",
"version": "wc-1.25.0",
"url": video_url,
"hh_ref": video_url,
"vid": vid,
"isfocustab": "1",
"isvisible": "1",
"idx": "0",
"val": "428",
"pid": pid,
"bi": "0",
"bt": "0",
"defn": "hd",
"vurl": vurl,
"step": "6",
"val1": "1",
"val2": "1",
"fact1": "",
"fact2": "",
"fact3": "",
"fact4": "",
"fact5": ""
}
res = requests.post(
url="https://btrace.yangshipin.cn/kvcollect",
params={"BossId": "2865"},
data=data,
headers={
'user-agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/102.0.0.0 Safari/537.36',
'referer': 'https://m.yangshipin.cn/',
}
)
def task(video_url):
try:
# https://w.yangshipin.cn/video?type=0&vid=g0000648jiz
vid = parse_qs(urlparse(video_url).query)['vid'][0]
guid = JS.call('createGuid')
pid = JS.call('createGuid')
flow_id = pid
platform = "4330701"
app_ver = "1.25.0"
ctime = str(int(time.time()))
ckey = create_ckey(vid, ctime, app_ver, platform, guid)
video_info_dict = get_video_info(vid, ctime, app_ver, platform, flow_id, guid, ckey)
vkey = video_info_dict["vl"]['vi'][0]['fvkey']
fn = video_info_dict["vl"]['vi'][0]['fn']
vurl = f"https://mp4playcloud-cdn.ysp.cctv.cn/{fn}?sdtfrom={platform}&guid={guid}&vkey={vkey}&platform=2"
play(platform, guid, video_url, vid, pid, vurl)
except Exception as e:
print(e)
def run():
video_url = "https://w.yangshipin.cn/video?type=0&vid=n000046gh5d" # 7431 ~ 7728
start = time.time()
pool = ThreadPoolExecutor(30)
for i in range(300):
pool.submit(task, video_url)
pool.shutdown()
end = time.time()
print("执行完成,耗时:", end - start)
if __name__ == '__main__':
run()
pyinstaller的例子
v2.py
import execjs
body = """
function createGuid(){
var e = (new Date).getTime().toString(36);
var r = Math.random().toString(36).replace(/^0./, "");
return "".concat(e, "_").concat(r);
}
"""
JS = execjs.compile(body)
guid = JS.call('createGuid')
print(guid)
input("回车继续")
pip install pyinstaller
#终端输入
pyinstaller -F v2.py -n demo
dist目录下:
打开终端运行
关于目录的bug
import os
import sys
base_dir = os.path.dirname(os.path.abspath(__file__))
print(base_dir)
file_path = os.path.join(base_dir, "db.txt")
print(file_path)
with open(file_path, mode='r', encoding='utf-8') as f:
data = f.read()
print(data)
这样会报错,运行exe的时候是到临时目录了
正确写法
import os
import sys
base_dir = os.path.dirname(os.path.realpath(sys.argv[0]))
# base_dir = os.path.dirname(os.path.abspath(__file__))
print(base_dir)
file_path = os.path.join(base_dir, "db.txt")
print(file_path)
with open(file_path, mode='r', encoding='utf-8') as f:
data = f.read()
print(data)
input("回车继续")