BP链接:通俗一些就是将你需要购买产品的规格全部放到一个链接里,点击这个链接之后,能直接跳转到提交订单界面,省去了选择参数的过程。
# 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
@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); } }
@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; } }
<!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>
本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。
我来说两句