专栏首页小锋学长生活大爆炸吱口令生成淘宝BP抢购链接

吱口令生成淘宝BP抢购链接

BP链接:通俗一些就是将你需要购买产品的规格全部放到一个链接里,点击这个链接之后,能直接跳转到提交订单界面,省去了选择参数的过程。

主代码

tool.py

# coding:utf-8

import requests
import re
import json
from bs4 import BeautifulSoup
from sys import argv
import io
import sys
import time
import random
sys.stderr = io.TextIOWrapper(sys.stderr.buffer, encoding='utf-8')
sys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding='utf-8')

from requests.packages import urllib3
urllib3.disable_warnings()

# 分隔符
SEPARATOR = '@#$%'

requests.DEFAULT_RETRIES = 5
headers = {
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.75 Safari/537.36',
    'Accept': '*/*',
    'accept-encoding': 'gzip, deflate, br',
    'accept-language': 'zh-CN,zh;q=0.9,en;q=0.8',
    'cache-control': 'no-cache',
    'sec-ch-ua': '"Chromium";v="86", "\"Not\\A;Brand";v="99", "Google Chrome";v="86"',
    'sec-ch-ua-mobile': '?0',
    'sec-fetch-dest': 'document',
    'sec-fetch-mode': 'navigate',
    'sec-fetch-site': 'same-origin',
    'sec-fetch-user': '?1',
    'upgrade-insecure-requests': '1',
    'pragma': 'no-cache',
 }


def getRedirUrl(share_msg):
    share_url = re.findall(r'https://[^\s]+', share_msg)[0]
    # 短链接获取真实链接
    html = requests.get(share_url, headers=headers, allow_redirects=False)
    real_url = re.findall("var url = '(.*?)'", html.text)
    if len(real_url) > 0:
        # 真实链接获取重定向后的链接
        real_url = real_url[0]
        real_url_tail = real_url.split('.htm?')[1]
        id = real_url.split('.htm?')[0].split('/')[-1][1:]
        redirect_url = r'https://detail.tmall.com/item.htm?id={}'.format(id)
        return id, redirect_url
    else:
        return None, None


def getGoodsProp(url):
    if url == None:
        return None, None
    # 获取商品页面内容
    html = requests.get(url, headers=headers, verify=False)
    # 获取商品属性
    soup = BeautifulSoup(html.text, 'lxml')
    tb_sku = soup.find(class_='tb-sku')
    tm_sale_prop = tb_sku.find_all(name='dl', class_='tm-sale-prop')
    prop = []
    temp = []
    for i in range(len(tm_sale_prop)):
        item = tm_sale_prop[i]
        li = item.find_all(name='li')
        for l in li:
            data_value = l['data-value']
            tilte = l.getText().strip()
            temp.append(tilte+SEPARATOR+data_value)
        prop.append(temp.copy())
        temp.clear()
    # 获取商品所有类别的skuid
    goods_content = re.findall(r'{"valItemInfo":(.*?}])', html.text)
    skuList = {}
    if len(goods_content) > 0:
        goods_content = goods_content[0] + "}"
        # print(goods_content)
        goods_dict = json.loads(goods_content)
        skuList = goods_dict["skuList"]
    return prop, skuList


def chooseGoodsProp(props):
    cnt1 = 1
    for prop in props:
        print(">> 属性: "+str(cnt1))
        cnt1 += 1
        cnt2 = 1
        for p in prop:
            print(str(cnt2)+": "+p)
            cnt2 += 1
        print()
    user = input(">> 请选择属性,若有多个属性请以空格分割(如'1 2'): ").strip().split(' ')
    res = ""
    for i in range(len(props)):
        res = res + props[i][int(user[i])-1].split(SEPARATOR)[1] + ";"
    return res


def listGoodsProp(props):
    cnt1 = 1
    for prop in props:
        print(">> 属性: "+str(cnt1))
        cnt1 += 1
        cnt2 = 1
        for p in prop:
            print(str(cnt2)+": "+p)
            cnt2 += 1
        print()


def chooseGoodsProp_spring(props, user):
    user = user.strip().split(',')
    res = ""
    for i in range(len(props)):
        res = res + props[i][int(user[i])-1].split(SEPARATOR)[1] + ";"
    return res


def getSkuid(choose, skuList):
    for item in skuList:
        if choose == item.get('pvs') + ";":
            return item.get('skuId')
    return None


def getBpUrl(itemId, skuId):
    bp_url = r'https://h5.m.taobao.com/cart/order.html?itemId={}&_input_charset=utf-8&buyNow=true&v=0&skuId={}'.format(itemId, skuId)
    return bp_url


def main():
    share_msg = input("输入淘宝商品吱口令: ")
    # 从吱口令获取商品id和真实链接
    itemId, redirect_url = getRedirUrl(share_msg)
    print("itemId: "+itemId)
    print("redirect_url: "+redirect_url)
    # 获取商品属性
    prop, skuList = getGoodsProp(redirect_url)
    print("skuList: " + str(skuList))
    # 用户选择属性
    choose = chooseGoodsProp(prop)
    # 获取属性对应的skuid
    skuId = getSkuid(choose, skuList)
    print("skuId: "+str(skuId))
    bp_url = getBpUrl(itemId, skuId)
    print("bp链接: "+bp_url)
    # resulPrint.clear()
    # resulPrint["itemId"] = itemId
    # resulPrint["redirect_url"] = redirect_url
    # resulPrint["prop"] = prop
    # resulPrint["skuList"] = skuList
    # resulPrint["bp"] = bp_url
    # print(json.dumps(resulPrint))


resulPrint = {}
def spring():
    # print("Python Interface")
    mode = argv[1]
    if mode == '1':
        share_msg = argv[2]
        # 从吱口令获取商品id和真实链接
        itemId, redirect_url = getRedirUrl(share_msg)
        # print("itemId: "+itemId)
        # print("redirect_url: "+redirect_url)
        # 获取商品属性
        retry = 0
        while True:
            try:
                prop, skuList = getGoodsProp(redirect_url)
                break
            except Exception as e:
                if retry >= 5:
                    raise Exception("淘宝访问超时")
                else:
                    retry += 1
                    time.sleep(random.randint(1, 4))
        # prop, skuList = getGoodsProp(redirect_url)
        # print("prop: " + str(prop))
        # print("skuList: " + str(skuList))
        resulPrint.clear()
        resulPrint["itemId"] = itemId
        resulPrint["redirect_url"] = redirect_url
        resulPrint["prop"] = prop
        resulPrint["skuList"] = skuList
        print(json.dumps(resulPrint))

    elif mode == '2':
        itemId = argv[2]
        redirect_url = argv[3]
        user = argv[4]
        # 获取商品属性
        retry = 0
        while True:
            try:
                prop, skuList = getGoodsProp(redirect_url)
                break
            except Exception as e:
                if retry >= 5:
                    raise Exception("淘宝访问超时")
                else:
                    retry += 1
                    time.sleep(random.randint(1, 4))
        # 用户选择属性
        choose = chooseGoodsProp_spring(prop, user)
        # 获取属性对应的skuid
        skuId = getSkuid(choose, skuList)
        # print("skuId: "+skuId)
        bp_url = getBpUrl(itemId, skuId)
        # print("bp链接: "+bp_url)
        resulPrint.clear()
        resulPrint["bp"] = bp_url
        print(json.dumps(resulPrint))


if __name__ == '__main__':
    main()
    # try:
    #     spring()
    # except Exception as e:
    #     # print(e)
    #     resulPrint.clear()
    #     resulPrint["err"] = 500
    #     resulPrint["errmsg"] = str(e)
    #     print(json.dumps(resulPrint))

待解决问题:

getGoodsProp函数中访问淘宝的https链接,经常报HTTPSConnectionPool错

附录

笔记:https://blog.csdn.net/sxf1061700625/article/details/109443161

userController.java

@RestController
public class UserController {

    @Autowired
    private UserService userService;

    @RequestMapping("/")
    public String index() {
        return "hello";
    }

    @RequestMapping("/getRedirUrl")
    public Result getRedirUrl(String shareMsg) {
        System.out.println(">> getRedirUrl");
        return userService.getRedirUrl(shareMsg);
    }

    @RequestMapping("/getGoodsProp")
    public Result getGoodsProp(String shareMsg) {
        System.out.println(">> getGoodsProp");
        return userService.getGoodsProp(shareMsg);
    }

    @RequestMapping("/getBpUrl")
    public Result getBpUrl(String itemId, String url, String user) {
        System.out.println(">> getBpUrl");
        return userService.getBpUrl(itemId, url, user);
    }

    @RequestMapping("/test")
    public Result test() {
        System.out.println(">> test");
        String str = "{\"itemId\": \"620278928010\", \"redirect_url\": \"https://detail.tmall.com/item.htm?id=620278928010&price=99-269&sourceType=item&sourceType=item&suid=b1b5b243-35c5-4fc5-a9c3-749e47bb012f&shareUniqueId=4948880474&ut_sk=1.XXsflQSA7sEDABWrN6TsGosi_21646297_1604370916299.Copy.1&un=4c4cd55ba530f81c4c6e4bed9157ce66&share_crt_v=1&spm=a2159r.13376460.0.0&sp_tk=U2FBbGNRTDRoTnE=&cpp=1&shareurl=true&short_name=h.4dacF0M&bxsign=scd6Cbz98QmcArDdLbgBZndmCgDDaXinqw3awZ6h3gfbCCnNQU5dPd_JaAnQOlsnPOzrRElx9xVqODJq1NHO2x270LHwIfabKtrPjV8DXZUpMU\", \"prop\": [[\"\\u5c0f\\u7c73\\u624b\\u73af5@#$%1627207:3232483\", \"\\u5c0f\\u7c73\\u624b\\u73af5\\u3010\\u987a\\u4e30\\u5feb\\u9012\\u3011@#$%1627207:3232484\", \"\\u5c0f\\u7c73\\u624b\\u73af5NFC@#$%1627207:60092\", \"\\u5c0f\\u7c73\\u624b\\u73af5NFC\\u3010\\u987a\\u4e30\\u5feb\\u9012\\u3011@#$%1627207:3232482\", \"\\u2605\\u2605\\u2605\\u5c0f\\u7c73\\u624b\\u73af 4 NFC \\u2605\\u2605\\u2605@#$%1627207:28332\", \"\\u2605\\u2605\\u2605\\u5c0f\\u7c73\\u624b\\u73af 4  \\u2605\\u2605\\u2605@#$%1627207:3232478\", \"\\u5c0f\\u7c73\\u624b\\u73af3 NFC \\uff08\\u7ecf\\u5178\\u8001\\u6b3e\\uff09@#$%1627207:3232481\"]], \"skuList\": [{\"names\": \"\\u519b\\u7eff\\u8272 \", \"pvs\": \"1627207:3232483\", \"skuId\": \"4556051290889\"}, {\"names\": \"\\u5929\\u84dd\\u8272 \", \"pvs\": \"1627207:3232484\", \"skuId\": \"4568862370599\"}, {\"names\": \"\\u6d45\\u9ec4\\u8272 \", \"pvs\": \"1627207:60092\", \"skuId\": \"4556051290890\"}, {\"names\": \"\\u6df1\\u5361\\u5176\\u5e03\\u8272 \", \"pvs\": \"1627207:3232482\", \"skuId\": \"4398756481400\"}, {\"names\": \"\\u6d45\\u7070\\u8272 \", \"pvs\": \"1627207:28332\", \"skuId\": \"4398756481399\"}, {\"names\": \"\\u6df1\\u7070\\u8272 \", \"pvs\": \"1627207:3232478\", \"skuId\": \"4583347495714\"}, {\"names\": \"\\u5de7\\u514b\\u529b\\u8272 \", \"pvs\": \"1627207:3232481\", \"skuId\": \"4600967691345\"}]}";
        return new Result().ok(str);
    }
}

userService.java

@Service
public class UserService {
    public Result getRedirUrl(String shareMsg) {
        System.out.println(shareMsg);
        String itemId = "id", redirectUrl = "url";
        Map<String, Object> map = new HashMap<>(2);
        map.put("itemId", itemId);
        map.put("redirect_url", redirectUrl);
        Map<String, Object> res = new HashMap<>(1);
        res.put("msg", map);
        return new Result().ok(res);
    }


    public Result getGoodsProp(String shareMsg) {
        StringBuilder successSb = new StringBuilder();
        StringBuilder errorSb = new StringBuilder();
        try {
            String[] args = new String[] {"python", "C:\\Users\\10617\\Desktop\\tool.py", "1", shareMsg};
            Process process = Runtime.getRuntime().exec(args);
            BufferedReader successMsg = new BufferedReader(new InputStreamReader(process.getInputStream(), StandardCharsets.UTF_8));
            BufferedReader errorMsg = new BufferedReader(new InputStreamReader(process.getErrorStream(), StandardCharsets.UTF_8));
            String line;

            while ((line=successMsg.readLine())!=null) {
                System.out.println(line);
                successSb.append(line);
            }
            successMsg.close();
            errorMsg.close();
            process.waitFor();
        }catch (Exception e){
            e.printStackTrace();
            return new Result().error();
        }
        return new Result().ok(successSb.toString());
    }

    public Result getBpUrl(String itemId, String url, String user) {
        StringBuilder sb = new StringBuilder();
        try {
            String[] args = new String[] {"python", "C:\\Users\\10617\\Desktop\\tool.py", "2", itemId, url, user};
            Process process = Runtime.getRuntime().exec(args);
            BufferedReader successMsg = new BufferedReader(new InputStreamReader(process.getInputStream(), StandardCharsets.UTF_8));
            BufferedReader errorMsg = new BufferedReader(new InputStreamReader(process.getErrorStream(), StandardCharsets.UTF_8));
            String line;
            while ((line=successMsg.readLine())!=null) {
                System.out.println(line);
                sb.append(line);
            }
//            while ((line=errorMsg.readLine())!=null) {
//                System.out.println(line);
//            }
            successMsg.close();
            errorMsg.close();
            process.waitFor();
        }catch (Exception e){
            e.printStackTrace();
            return new Result().error();
        }
        return new Result().ok(sb.toString());
    }
}

Result.java

public class Result extends HashMap<String, Object> {
    public Result() {}

    public Result error(String msg) {
        Result r = new Result();
        r.put("code", 500);
        r.put("msg", msg);
        return r;
    }

    public Result error() {
        Result r = new Result();
        r.put("code", 500);
        r.put("msg", "未知错误");
        return r;
    }

    public Result ok() {
        Result r = new Result();
        r.put("code", 0);
        r.put("msg", "操作成功");
        return r;
    }

    public Result ok(String msg) {
        Result r = new Result();
        r.put("code", 0);
        r.put("msg", msg);
        return r;
    }

    public Result ok(List<Map<String, Object>>  list) {
        Result r = new Result();
        r.put("code", 0);
        r.put("msg", list);
        return r;
    }

    public Result ok(Map<String, Object>  map) {
        Result r = new Result();
        r.put("code", 0);
        r.putAll(map);
        return r;
    }
}

不带css的HTML测试页

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8" />
		<title></title>
		<script type="text/javascript" src="http://libs.baidu.com/jquery/2.0.0/jquery.min.js"></script>
	</head>
	<body>
		<button id="reload" style="display: block;">重置</button>
		<label>吱口令:</label>
		<br />
		<textarea id="shareMsg" name="shareMsg"></textarea>
		<button id="submit_1" style="display: block;">提交1</button>
		<br />
		<hr />
		
		<div id="goodsprop" style="display: none;">
			<div id="propbox"> </div>
			<div>
				<label>商品链接</label>
				<input type="text" id="redirurl"/>
			</div>
			<div>
				<label>商品ID</label>
				<input type="text" id="itemId"/>
			</div>
			<button id="submit_2" style="display: block;">提交2</button>
		</div>
		<br />
		<hr />
		
		<div id="bpurlbox" style="display: none;">
			<label>BP链接</label>
			<input type="text" id="bpurl"/>
		</div>
	</body>
	
	<script type="text/javascript">
		// https://www.w3school.com.cn/jquery/ajax_ajax.asp
		// https://www.w3school.com.cn/jquery/ajax_get.asp
		// https://blog.csdn.net/assiduous_me/article/details/90108590
		var targetUrl = "http://192.168.1.107:8080/";//"http://127.0.0.1:8080/";
		$(document).ready(function(){
			$("#submit_1").click(function(){
				// 删除所有子元素
				$("#propbox").empty();
				var url = targetUrl+"getGoodsProp?shareMsg="+$("#shareMsg").val();
				var url_test = targetUrl+"test";
				$.ajax({
					type: "GET",
					url: url,  // 测试时用:url_test
					data: {shareMsg: $("#shareMsg").val()},
					dataType: "json",
					success: function(response, status) {
						if(status == "success") {
							var code = response.code
							if(code==0) {
								var msg = JSON.parse(response.msg)
								// 如果存在
								if(msg.err) {
									alert("接口调用超时,可稍后再试: "+msg.errmsg);
									console.log(msg.errmsg);
								}else {
									// 禁用按钮1
									$("#submit_1").attr("disabled", true);
									var itemId = msg.itemId
									var redirect_url = msg.redirect_url
									var prop = msg.prop
									var skuList = msg.skuList
						
									// 显示下拉选择框
									for(var outer=0; outer<prop.length; outer++) {
										$("#propbox").append("<select id='prop"+outer+"'></select><br />");
										for(var inner=0; inner<prop[outer].length; inner++) {
											// console.log(outer + " " + inner)
											$("#prop"+outer).append("<option value="+(inner+1)+">"+prop[outer][inner].split("@#$%")[0]+"</option>");
										}
									}
									// 显示重定向URL
									$("#itemId").val(itemId);
									// 显示重定向URL
									$("#redirurl").val(redirect_url);
									console.log(skuList.length)
									// 显示元素
									$("#goodsprop").show();
								}
							}else {
								console.log("code: "+code+"\n")
							}
							
						}else {
							alert("错误");
						}
					}
				});
			});
		});
		
		
		$(document).ready(function(){
			$("#submit_2").click(function(){
				$("#bpurl").val("");
				var user = "";
				for(var i=0; i<$("#propbox").children().length/2; i++) {
					user = user + $("#prop"+i).val() + ",";
				}
				// 去掉最后多余的逗号
				// console.log($("#propbox").children().length);
				user = user.substring(0, user.length-1);
				// console.log($("#itemId").val()+" "+$("#redirurl").val()+" "+user)
				var url = targetUrl+"getBpUrl";
				var url_test = targetUrl+"test";
				$.ajax({
					type: "GET",
					url: url,
					data: {
						itemId: $("#itemId").val(),
						url: $("#redirurl").val(),
						user: user
					},
					dataType: "json",
					success: function(response, status) {
						if(status == "success") {
							console.log(response);
							var code = response.code;
							if(code == 0) {
								var msg = JSON.parse(response.msg)
								if(msg.err) {
									alert("接口调用错误,可稍后再试:"+msg.errmsg);
									console.log(msg.errmsg);
								}else {
									// 启用按钮1
									$("#submit_1").attr("disabled", false);
									console.log("成功");
									alert("成功!");
									var bp = msg.bp;
									$("#bpurl").val(bp);
									$("#bpurlbox").show();
								}
							}else {
								console.log("code: "+code+"\n")
							}
						}else {
							alert("错误");
						}
					}
				});
			});
		});
		
		$(document).ready(function(){
			$("#reload").click(function(){
				window.location.reload();
			});
		});
	</script>
</html>

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • Python 将土味情话语录设置为桌面壁纸

    小锋学长
  • Java入门编程练习题

    1、第n行有n个数字 2、每一行的开始和结尾数字都为1 3、第n+1行的第i个数字等于第n行的i-1个数字加上第n行的i个数字

    小锋学长
  • 自己动手实现4大免费聊天机器人:小冰、图灵、腾讯、青云客

    聊天机器人(Chatterbot)是经由对话或文字进行交谈的计算机程序。能够模拟人类对话,通过图灵测试,如Siri、小爱同学、微软小冰等。

    小锋学长
  • Java面试-List中的sort详细解读

    最近看了一些排序相关的文章,因此比较好奇,Java中的排序是如何做的。本篇文章介绍的是JDK1.8,List中的sort方法。

    健程之道
  • 如何使特定的数据高亮显示?

    当表格里数据比较多时,很多时候我们为了便于观察数据,会特意把符合某些特征的数据行高亮显示出来。这不,公司的HR小姐姐就有这个需求,说她手头上有一份招聘数据,她想...

    猴子聊数据分析
  • 拿好了!Linux 运维必备的 13 款实用工具!

    本文介绍几款 Linux 运维比较实用的工具,希望对 Linux 运维人员有所帮助。

    小小科
  • FreeSWITCH作为传真机时

    FreeSWITCH的mod_spandsp模块提供了基于SIP的传真收发功能,但是mod_spandsp仅限于tiff文件,我们平时要发送的传真文件大部分是非...

    用户1506126
  • Linux 运维必备的13款实用工具,拿好了~

    下载:http://sourceforge.net/projects/nethogs/files/nethogs/0.8/nethogs-0.8.0.tar.g...

    lyb-geek
  • Linux 运维必备的 13 款实用工具,拿好了~

    本文介绍几款 Linux 运维比较实用的工具,希望对 Linux 运维人员有所帮助。 1. 查看进程占用带宽情况 - Nethogs Nethogs 是一个...

    小小科
  • 【软件测试】面试中问到Linux命令,你都答上来了吗?【送书】

    Linux 替换文件内容 sed命令下批量替换文件内容 格式: sed -i “s/查找字段/替换字段/g” grep 查找字段 -rl 路径 文件名 -i 表...

    软测小生

扫码关注云+社区

领取腾讯云代金券