0

0

监测动态网页库存并发送Discord通知的Python教程

聖光之護

聖光之護

发布时间:2025-11-24 11:32:01

|

268人浏览过

|

来源于php中文网

原创

监测动态网页库存并发送Discord通知的Python教程

本教程旨在指导如何使用python监测网站上特定尺寸商品的库存状态,并在库存更新时通过discord发送通知。文章将深入探讨传统网络爬虫(如beautifulsoup)在处理javascript动态加载内容时的局限性,并介绍如何利用selenium等无头浏览器工具来克服这些挑战,实现对动态生成库存信息的准确抓取与实时监控。

1. 引言:库存监测与Discord通知的需求

在电子商务日益普及的今天,许多用户希望能够实时追踪特定商品的库存状态,尤其是一些热门或限量发售的商品。当商品重新有货时,通过自动化工具及时收到通知,可以大大提高抢购成功的几率。本教程将以监测特定尺寸(例如“40码”)的商品库存为例,并演示如何将库存更新信息发送至Discord频道。

2. 初始尝试与BeautifulSoup的局限性

最初的设想是使用requests库获取网页内容,并结合BeautifulSoup进行HTML解析,以查找库存信息。以下是用户尝试的初始代码结构:

import discord
from bs4 import BeautifulSoup
import requests
import aiohttp
import asyncio

webhook_url = 'YOUR_DISCORD_WEBHOOK_URL' # 替换为你的Discord Webhook URL

async def send_webhook_message(content):
    """
    通过Discord Webhook发送消息。
    """
    async with aiohttp.ClientSession() as session:
        async with session.post(webhook_url, json={"content": content}) as response:
            if response.status == 204:
                print("Discord message sent successfully.")
            else:
                print(f"Error sending Discord message. Status code: {response.status}")

async def check_stock_initial(url, size):
    """
    初步尝试检查库存,但存在局限性。
    """
    try:
        response = requests.get(url)
        response.raise_for_status() # 检查HTTP请求是否成功
        soup = BeautifulSoup(response.text, 'html.parser')
        # 尝试查找表示库存状态的元素
        stock_element = soup.find('li', {'class': 'unselectable'})

        # 这里的逻辑是判断如果找到'unselectable'则表示无货,否则可能是有货。
        # 但这并不能精确到特定尺寸,且未考虑动态内容。
        return stock_element is None 

    except requests.RequestException as e:
        print(f"Error making request to the website: {e}")
        return False

# ... (后续的main函数和异步运行逻辑)

问题分析:

  1. 'unselectable' 与 'selectable': 在许多网站上,表示商品有货或无货的HTML元素通常会通过类名(如selectable或unselectable)来区分。unselectable通常意味着无货,而selectable则意味着有货。因此,仅仅查找unselectable并不能直接判断特定尺寸是否有货。
  2. 特定尺寸的识别: 要检查特定尺寸(如“40码”)的库存,我们需要定位到代表该尺寸的元素,并判断其状态。通常,这些尺寸选项会以
  3. 或其他标签的形式存在,并通过title属性或文本内容来标识尺寸。
  4. 动态加载内容的核心问题: 最关键的问题在于,目标网站(如courir.com)上的库存信息,尤其是不同尺寸的可用性,是通过JavaScript在页面加载完成后动态生成的。requests库只能获取到服务器最初返回的HTML源代码,而无法执行JavaScript来渲染完整的页面。这意味着,在BeautifulSoup解析的HTML中,我们可能根本找不到那些由JavaScript生成的、包含库存信息的元素。

通过浏览器开发者工具(通常按F12打开),我们可以观察到,当页面加载完成后,表示尺寸选择的元素可能具有如下结构:

立即学习Python免费学习笔记(深入)”;

  • 然而,这些带有selectable类和title="40"的元素,在requests获取的原始HTML中是缺失的。

    3. 解决方案:使用无头浏览器处理动态内容

    为了解决JavaScript动态加载内容的问题,我们需要使用无头浏览器(Headless Browser)。无头浏览器是一种没有图形用户界面的浏览器,它可以在后台运行,模拟真实用户的行为(如加载页面、执行JavaScript、点击元素等),从而获取到完全渲染后的页面内容。

    VisualizeAI
    VisualizeAI

    用AI把你的想法变成现实

    下载

    常用的无头浏览器工具有:

    • Selenium: 一个功能强大的Web自动化测试框架,支持多种浏览器(Chrome, Firefox等),并提供Python绑定。
    • Playwright: Microsoft开发的新一代Web自动化库,支持Chromium, Firefox, WebKit,性能优异。
    • Puppeteer (Node.js): Google开发的Node.js库,用于控制Chrome/Chromium。

    本教程将以Selenium为例,演示如何获取动态加载的库存信息。

    3.1 环境准备

    1. 安装Selenium:
      pip install selenium
    2. 下载浏览器驱动: 根据你使用的浏览器(如Chrome)版本,下载对应的WebDriver。

    3.2 使用Selenium检查库存

    现在,我们将重写check_stock函数,使其使用Selenium来加载和解析页面。

    from selenium import webdriver
    from selenium.webdriver.chrome.service import Service
    from selenium.webdriver.common.by import By
    from selenium.webdriver.support.ui import WebDriverWait
    from selenium.webdriver.support import expected_conditions as EC
    from selenium.common.exceptions import TimeoutException, NoSuchElementException, WebDriverException
    import time # 用于等待
    
    # 配置ChromeDriver路径 (如果未添加到系统PATH)
    # service = Service(executable_path='/path/to/chromedriver') # 替换为你的chromedriver路径
    
    async def check_stock_selenium(url, target_size):
        """
        使用Selenium检查特定尺寸的库存。
        """
        options = webdriver.ChromeOptions()
        options.add_argument('--headless') # 启用无头模式,不显示浏览器界面
        options.add_argument('--disable-gpu') # 禁用GPU加速(Linux环境下推荐)
        options.add_argument('--no-sandbox') # 禁用沙箱模式(Linux环境下推荐)
        options.add_argument('user-agent=Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124124 Safari/537.36')
    
        driver = None
        try:
            # 初始化WebDriver
            # driver = webdriver.Chrome(service=service, options=options) # 如果指定了service
            driver = webdriver.Chrome(options=options) # 如果chromedriver在PATH中
    
            driver.get(url)
    
            # 等待页面元素加载完成。这里等待直到表示尺寸选择的某个元素出现。
            # 通常,尺寸选择器会有一个共同的父容器或类名。
            # 我们可以等待一个通用且稳定的元素,然后查找其内部的特定尺寸。
            # 示例:等待一个class为'product-size-selector'的div出现
            WebDriverWait(driver, 20).until(
                EC.presence_of_element_located((By.CSS_SELECTOR, 'ul.product-size-list'))
            )
    
            # 查找特定尺寸的元素。
            # CSS选择器:查找 class 为 'selectable' 的 li 元素,
            # 在其内部查找 class 为 'swatchanchor' 且 title 包含目标尺寸的 a 元素。
            # 注意:这里的选择器需要根据实际网站的HTML结构进行调整。
            size_element_selector = f"li.selectable a.swatchanchor[title*='{target_size}']"
    
            try:
                # 尝试查找目标尺寸的“有货”元素
                size_40_available = driver.find_element(By.CSS_SELECTOR, size_element_selector)
                # 如果找到,则表示该尺寸有货
                print(f"Size {target_size} is in stock!")
                return True
            except NoSuchElementException:
                # 如果没有找到,则表示该尺寸无货
                print(f"Size {target_size} is out of stock.")
                return False
    
        except TimeoutException:
            print(f"Timeout waiting for page elements to load on {url}")
            return False
        except WebDriverException as e:
            print(f"WebDriver error: {e}")
            return False
        except Exception as e:
            print(f"An unexpected error occurred: {e}")
            return False
        finally:
            if driver:
                driver.quit() # 确保关闭浏览器实例
    

    3.3 整合到异步监测循环

    现在,我们可以将新的check_stock_selenium函数整合到原有的异步监测循环中。

    # ... (send_webhook_message 函数保持不变)
    
    product_data = [
        {'url': 'https://www.courir.com/fr/p/ugg-tasman-1499533.html', 'size': '40'}, # 目标尺寸改为'40'
    ]
    
    async def main():
        previous_stock_status = {}  # 存储上一次的库存状态
    
        while True:
            result_message = ""
    
            for product_info in product_data:
                url = product_info['url']
                size = product_info['size']
    
                # 使用Selenium检查库存
                current_stock_status = await check_stock_selenium(url, size)
    
                # 检查库存状态是否发生变化
                if not previous_stock_status.get(url, {}).get(size, False) and current_stock_status:
                    result_message += f"商品 {url} 的 {size} 码现在有货!\n"
    
                # 更新当前库存状态
                previous_stock_status.setdefault(url, {})[size] = current_stock_status
    
            if result_message: # 只有当有更新时才发送Discord消息
                print(result_message.strip())
                await send_webhook_message(result_message)
                print("已发送Discord消息。")
            else:
                print("无库存更新。")
    
            print("等待10分钟进行下一次检查...")
            await asyncio.sleep(600)  # 睡眠10分钟 (600秒)
    
    if __name__ == "__main__":
        asyncio.run(main())

    4. 注意事项与最佳实践

    1. 网站结构变化: 动态网站的HTML结构可能会频繁变动,导致CSS选择器失效。定期检查并更新选择器是必要的维护工作。
    2. 反爬机制: 网站可能会有反爬虫机制,如IP封锁、验证码等。
      • User-Agent: 使用真实的User-Agent头。
      • 代理IP: 考虑使用代理IP池来分散请求,避免IP被封。
      • 请求频率: 控制请求频率,模拟人类浏览行为,避免过于频繁的请求。asyncio.sleep是关键。
      • Headless检测: 有些网站能检测出无头浏览器。可以通过设置更多浏览器选项(如禁用自动化标志、伪装为真实浏览器)来规避。
    3. 错误处理: 增加更健壮的错误处理机制,例如针对NoSuchElementException、TimeoutException等。
    4. 资源消耗: 无头浏览器比requests消耗更多的系统资源(CPU和内存)。在部署时需考虑服务器性能。
    5. 异步编程: aiohttp和asyncio在处理网络请求和并发任务时非常高效,但需要确保所有I/O操作都是异步的。Selenium本身是同步的,但在async函数中调用它不会阻塞整个事件循环,只是会等待其完成。
    6. Discord Webhook安全性: 妥善保管你的Discord Webhook URL,避免泄露。

    5. 总结

    通过本教程,我们了解了在处理JavaScript动态加载内容的网站时,传统网络爬虫(如BeautifulSoup)的局限性。为了准确获取特定尺寸商品的库存信息,我们必须转向使用Selenium等无头浏览器工具来模拟用户行为,执行JavaScript并渲染完整页面。结合异步编程和Discord Webhook,我们可以构建一个高效、实用的库存监测和通知系统。然而,持续维护和应对网站反爬机制是此类自动化工具长期运行的关键。

    相关专题

    更多
    python开发工具
    python开发工具

    php中文网为大家提供各种python开发工具,好的开发工具,可帮助开发者攻克编程学习中的基础障碍,理解每一行源代码在程序执行时在计算机中的过程。php中文网还为大家带来python相关课程以及相关文章等内容,供大家免费下载使用。

    755

    2023.06.15

    python打包成可执行文件
    python打包成可执行文件

    本专题为大家带来python打包成可执行文件相关的文章,大家可以免费的下载体验。

    636

    2023.07.20

    python能做什么
    python能做什么

    python能做的有:可用于开发基于控制台的应用程序、多媒体部分开发、用于开发基于Web的应用程序、使用python处理数据、系统编程等等。本专题为大家提供python相关的各种文章、以及下载和课程。

    758

    2023.07.25

    format在python中的用法
    format在python中的用法

    Python中的format是一种字符串格式化方法,用于将变量或值插入到字符串中的占位符位置。通过format方法,我们可以动态地构建字符串,使其包含不同值。php中文网给大家带来了相关的教程以及文章,欢迎大家前来阅读学习。

    618

    2023.07.31

    python教程
    python教程

    Python已成为一门网红语言,即使是在非编程开发者当中,也掀起了一股学习的热潮。本专题为大家带来python教程的相关文章,大家可以免费体验学习。

    1262

    2023.08.03

    python环境变量的配置
    python环境变量的配置

    Python是一种流行的编程语言,被广泛用于软件开发、数据分析和科学计算等领域。在安装Python之后,我们需要配置环境变量,以便在任何位置都能够访问Python的可执行文件。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

    547

    2023.08.04

    python eval
    python eval

    eval函数是Python中一个非常强大的函数,它可以将字符串作为Python代码进行执行,实现动态编程的效果。然而,由于其潜在的安全风险和性能问题,需要谨慎使用。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

    577

    2023.08.04

    scratch和python区别
    scratch和python区别

    scratch和python的区别:1、scratch是一种专为初学者设计的图形化编程语言,python是一种文本编程语言;2、scratch使用的是基于积木的编程语法,python采用更加传统的文本编程语法等等。本专题为大家提供scratch和python相关的文章、下载、课程内容,供大家免费下载体验。

    707

    2023.08.11

    Golang gRPC 服务开发与Protobuf实战
    Golang gRPC 服务开发与Protobuf实战

    本专题系统讲解 Golang 在 gRPC 服务开发中的完整实践,涵盖 Protobuf 定义与代码生成、gRPC 服务端与客户端实现、流式 RPC(Unary/Server/Client/Bidirectional)、错误处理、拦截器、中间件以及与 HTTP/REST 的对接方案。通过实际案例,帮助学习者掌握 使用 Go 构建高性能、强类型、可扩展的 RPC 服务体系,适用于微服务与内部系统通信场景。

    8

    2026.01.15

    热门下载

    更多
    网站特效
    /
    网站源码
    /
    网站素材
    /
    前端模板

    精品课程

    更多
    相关推荐
    /
    热门推荐
    /
    最新课程
    Sass 教程
    Sass 教程

    共14课时 | 0.8万人学习

    Bootstrap 5教程
    Bootstrap 5教程

    共46课时 | 2.9万人学习

    CSS教程
    CSS教程

    共754课时 | 19.2万人学习

    关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
    php中文网:公益在线php培训,帮助PHP学习者快速成长!
    关注服务号 技术交流群
    PHP中文网订阅号
    每天精选资源文章推送

    Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号