队列获取任务

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目录下:

订单播放项目的回顾八,客户端操作_ci

打开终端运行

订单播放项目的回顾八,客户端操作_ci_02

关于目录的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("回车继续")