需要提前完成以下3项操作,确保后续代码能正常运行
创建名为jd_coupon.py的文件,先写入以下导入部分
```python from selenium import webdriver from selenium.webdriver.common.by import By from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.support import expected_conditions as EC from bs4 import BeautifulSoup import pandas as pd from fake_useragent import UserAgent import time from itertools import combinations ```
在导入库下方继续写入完整的京东凑单类代码
```python class JD_CouponHelper: def __init__(self, target_url, coupon_min, coupon_max, coupon_save): 初始化:目标商品页、满减参数(满coupon_min减coupon_save,当前购物车或收藏夹已选总价coupon_max) self.target_url = target_url self.coupon_min = coupon_min self.coupon_max = coupon_max self.coupon_save = coupon_save self.driver = self._init_driver() self.candidate_products = [] def _init_driver(self): 初始化Chrome无头模式(可选)+ 反爬UserAgent options = webdriver.ChromeOptions() options.add_argument('--headless') 如需隐藏浏览器取消注释 options.add_argument(f'user-agent={UserAgent().random}') options.add_argument('--disable-blink-features=AutomationControlled') driver = webdriver.Chrome(options=options) driver.execute_cdp_cmd('Page.addScriptToEvaluateOnNewDocument', { 'source': 'Object.defineProperty(navigator, "webdriver", {get: () => undefined})' }) return driver def login_jd(self): 扫码登录京东(5分钟内完成扫码) print("请在弹出的浏览器中5分钟内完成京东扫码登录") self.driver.get('https://passport.jd.com/new/login.aspx') WebDriverWait(self.driver, 300).until( EC.presence_of_element_located((By.CLASS_NAME, 'nickname')) ) print("登录成功!") def search_candidates(self, search_keyword="京东自营 小物件 凑单"): 搜索凑单候选商品 self.driver.get(f'https://search.jd.com/Search?keyword={search_keyword}&enc=utf-8&wq={search_keyword}') WebDriverWait(self.driver, 20).until( EC.presence_of_element_located((By.CLASS_NAME, 'gl-i-wrap')) ) 滚动加载更多(每次滚动到底部加载剩余商品) for i in range(3): self.driver.execute_script("window.scrollTo(0, document.body.scrollHeight);") time.sleep(2) 解析商品信息 soup = BeautifulSoup(self.driver.page_source, 'html.parser') items = soup.find_all('div', class_='gl-i-wrap') for item in items: try: 只取有货、自营(可自己修改)、京东物流 if item.find('div', class_='p-stock') and '自营' in str(item) and '无货' not in item.find('div', class_='p-stock').text: continue price_str = item.find('div', class_='p-price').find('i').text.strip() price = float(price_str) name = item.find('div', class_='p-name').find('em').text.strip() link = 'https:' + item.find('div', class_='p-name').find('a')['href'] self.candidate_products.append({ 'name': name, 'price': price, 'link': link }) except Exception as e: continue print(f"共获取到{len(self.candidate_products)}个候选凑单商品") def find_best_combination(self, max_num=3): 寻找最优凑单组合:剩余金额最小(接近满减额即可),商品数量最少 remaining_needed = max(0, self.coupon_min - self.coupon_max) if remaining_needed == 0: print("当前已满足满减条件!无需凑单") return print(f"当前还需要凑单金额:{remaining_needed:.2f}元") best_comb = None min_remain = float('inf') min_count = max_num + 1 遍历1-3个商品的组合 for num in range(1, max_num+1): for comb in combinations(self.candidate_products, num): total = sum([p['price'] for p in comb]) if total >= remaining_needed: current_remain = total - remaining_needed current_count = num 先看剩余金额更小,再看数量更少 if current_remain < min_remain or (current_remain == min_remain and current_count < min_count): min_remain = current_remain min_count = current_count best_comb = comb if best_comb: print("找到最优凑单组合:") for p in best_comb: print(f"商品名:{p['name']},价格:{p['price']:.2f}元,链接:{p['link']}") print(f"凑单总额:{sum([p['price'] for p in best_comb]):.2f}元,满减后总支付:{(self.coupon_max + sum([p['price'] for p in best_comb]) - self.coupon_save):.2f}元") 保存到Excel df = pd.DataFrame(best_comb) df.to_excel('jd_coupon_best_comb.xlsx', index=False) print("最优组合已保存到jd_coupon_best_comb.xlsx") else: print("未找到符合条件的凑单组合,请尝试扩大搜索范围或增加凑单商品最大数量") def close_driver(self): 关闭浏览器 self.driver.quit() ```在jd_coupon.py文件末尾继续写入调用代码
```python if __name__ == "__main__": 这里修改以下参数即可 TARGET_URL = "https://item.jd.com/100012043978.html" 换成你已选的商品链接(可选,仅用于参考) COUPON_MIN = 300 满减门槛 COUPON_MAX = 275.8 当前购物车/收藏夹已选商品的总价(精确到分) COUPON_SAVE = 50 满减金额 SEARCH_KEYWORD = "京东自营 零食 小包装 凑单" 自定义凑单关键词,可多次更换 MAX_NUM = 3 最多选几个凑单商品 helper = JD_CouponHelper(TARGET_URL, COUPON_MIN, COUPON_MAX, COUPON_SAVE) try: helper.login_jd() helper.search_candidates(SEARCH_KEYWORD) helper.find_best_combination(MAX_NUM) finally: helper.close_driver() ```易频IT社区是综合性互联网IT技术门户网站,专注分享网络技术、服务器运维、网络安全、编程开发、系统架构、云计算、大数据等行业干货,实时更新IT行业资讯、零基础教程、实战案例,为IT从业者、技术爱好者提供专业的学习交流平台。
Copyright © 2021-2026 易频IT社区. All Rights Reserved. 备案号:闽ICP备2023013482号 网站地图