python - 如果不是 http 200 状态,如何比较变量
问题描述
我目前已经编写了一个网络抓取,我在其中比较了两个值,以查看之前请求与新请求相比是否有任何增加的值。
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()
我面临的问题是存在产品可以被取下来的情况。例如,如果我现在找到['US 9,5/EUR 43', 'US 10,5/EUR 44,5']
了尺寸并且网页被管理员删除并返回 404。几个小时后,他们重新添加网页并再次添加值['US 9,5/EUR 43', 'US 10,5/EUR 44,5']
- 这不会打印我们之前已经拥有的值我们之前的有效请求。
我想知道如果网页从 404 返回到 200(即使它们添加相同的值?),打印出这些值的最佳方法是什么?
解决方案
在这种情况下使用response.raise_for_status()
不正确。如果网站返回 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(...)
已被删除,因为当某些内容从网站上删除时它不会捕获,只有在添加某些内容时才会捕获。如果某些内容首先被删除然后重新添加,那么它也会被您的程序捕获。
推荐阅读
- html - CSS 属性裁剪颜色背景
- ios - iOS 应用程序在启动时崩溃
- asp.net-web-api - 如何在 asp.net web api 中自定义 OAuthAuthorizationServerProvider 的错误消息?
- javascript - 使用插槽将行模板从父组件传递到 vue boostrap 表
- jquery - 单击按钮时数据表中的过滤器值不保留
- visual-studio - 在没有管理员权限的情况下将调试器附加到本地 IIS
- mysql - Mysql 简化查询以保持没有子查询
- php - URL段的php slim丢失数据:id
- java - 我无法访问对象属性
- r - 以长格式创建随机组变量