如果不是 http 200 状态,如何比较变量

How to compare variables if not http 200 status

我目前写了一个网络抓取,我在其中比较两个值,看看与新请求相比,以前的请求是否有任何增加的值。

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

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) -> Optional['Product']:
        with requests.get(url) as response:
            response.raise_for_status()
            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 cls(
            name=name and name.text.strip(),
            price=price and price.text.strip(),
            image=image and image['content'],
            sizes=cls.get_sizes(doc),
        )


def main():
    product = Product.from_page("https://shelta.se/sneakers/nike-air-zoom-type-whiteblack-cj2033-103")

    previous_request = product.sizes

    while True:
        product = Product.from_page("https://shelta.se/sneakers/nike-air-zoom-type-whiteblack-cj2033-103")

        if set(product.sizes) - set(previous_request):
            print("new changes on the webpage")
            previous_request = product.sizes

        else:
            print("No changes made")

        time.sleep(500)


if __name__ == '__main__':
    main()

我现在面临的问题是有一个场景可以下架产品。例如,如果我现在找到 sizes['US 9,5/EUR 43', 'US 10,5/EUR 44,5'] 并且该网页被管理员删除 returns 404。几个小时后他们重新添加网页并再次添加值 ['US 9,5/EUR 43', 'US 10,5/EUR 44,5']- 这不会打印我们之前有效请求中已有的值。

我想知道如果网页 returns 从 404 返回到 200(即使它们添加相同的值?)

,打印这些值的最佳方法是什么?

在这种情况下 response.raise_for_status() 的使用是不正确的。如果网站 returns 出现 404、500 或类似错误,退出您的程序,这只会引发异常。将 response.raise_for_status() 更改为:

if response.status_code is not 200:
    return cls(None,None,None,None)

编辑 因为我误解了问题:

如果发生错误,现在将返回空产品。现在唯一需要检查的是尺寸是否发生了变化。

def main():
    url = "https://shelta.se/sneakers/nike-air-zoom-type-whiteblack-cj2033-103"

    previous_product = Product.from_page(url) 
    while True:
        product = Product.from_page(url)
        
        if not product.sizes == previous_product.sizes:
            print("new changes on the webpage")
        else:
            print("No changes made")
        
        previous_product = product
        time.sleep(500)

previous_product 已移出。在这种情况下,这无关紧要,但它提高了可读性。

set(...) - set(...) 的使用已被删除,因为当从网站上删除某些内容时它不会捕获,只有当添加某些内容时才会捕获。如果某些内容先被删除然后重新添加,它也会被您的程序捕获。