You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

HTTP非200场景下变量对比方案:404恢复后如何触发通知

解决方案

核心改动思路

  • 改造Product.from_page方法,捕获所有请求、解析阶段的异常,返回「请求是否成功」「产品实例/None」两个值,避免遇到404直接导致程序崩溃
  • 新增两个状态变量:存储上一次请求成功时的尺码列表、标记上一次请求是否处于失败状态
  • 新增状态切换判断逻辑:当本次请求成功、且上一次请求失败时,直接触发页面恢复通知,不受尺码对比结果影响
  • 仅在请求成功时更新上一次有效尺码,失败时保留原有有效尺码,保证对比基准不会被无效请求覆盖

修改后完整代码

import json
import re
import time
from dataclasses import dataclass
from typing import Optional, List, Tuple

import requests
from bs4 import BeautifulSoup


@dataclass
class Product:
    name: Optional[str]
    price: Optional[str]
    image: Optional[str]
    sizes: List[str]

    @staticmethod
    def get_sizes(doc: BeautifulSoup) -> List[str]:
        pat = re.compile(
            r'^<script>var JetshopData='
            r'(\{.*\})'
            r';</script>$',
        )
        for script in doc.find_all('script'):
            match = pat.match(str(script))
            if match is not None:
                break
        else:
            return []

        data = json.loads(match[1])
        return [
            variation
            for get_value in data['ProductInfo']['Attributes']['Variations']
            if get_value.get('IsBuyable')
            for variation in get_value['Variation']
        ]

    @classmethod
    def from_page(cls, url: str) -> Tuple[bool, Optional['Product']]:
        try:
            # 增加超时设置避免无限挂起
            with requests.get(url, timeout=10) as response:
                if response.status_code != 200:
                    return False, None
                doc = BeautifulSoup(response.text, 'html.parser')

            name = doc.select_one('h1.product-page-header')
            price = doc.select_one('span.price')
            image = doc.select_one('meta[property="og:image"]')

            return True, cls(
                name=name and name.text.strip(),
                price=price and price.text.strip(),
                image=image and image['content'],
                sizes=cls.get_sizes(doc),
            )
        # 捕获所有请求、解析异常,统一归为请求失败
        except Exception:
            return False, None


def main():
    target_url = "https://shelta.se/sneakers/nike-air-zoom-type-whiteblack-cj2033-103"
    # 初始化状态变量
    last_success_sizes = []
    last_request_failed = False

    # 首次请求初始化状态
    init_success, init_product = Product.from_page(target_url)
    if init_success:
        last_success_sizes = init_product.sizes
        last_request_failed = False
    else:
        last_request_failed = True

    while True:
        req_success, product = Product.from_page(target_url)
        if req_success:
            current_sizes = product.sizes
            # 判断是否从异常状态恢复
            if last_request_failed:
                print("页面已从异常状态恢复,商品重新上架")
                last_request_failed = False
            # 原有新增尺码判断逻辑
            new_sizes = set(current_sizes) - set(last_success_sizes)
            if new_sizes:
                print(f"检测到新增尺码: {new_sizes}")
                last_success_sizes = current_sizes
            else:
                print("无新增尺码")
        else:
            print("页面请求失败,商品可能已下架")
            last_request_failed = True

        time.sleep(500)


if __name__ == '__main__':
    main()

内容的提问来源于stack exchange,提问作者PythonNewbie

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.12 14:57:00