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
相关产品推荐
相关产品推荐

