Python实现什么值得买网站的定时检测爬虫

https://github.com/SheldonZheng/SMZDM_Monitor

昨天写的一个什么值得买网站的监测爬虫;可以实现检测指定关键字,如果出现关键字匹配的内容发送邮件到指定邮箱。

代码写的很烂 第一次用 python 写东西 轻喷

Usage 里写的不太详细 改改文件开头的那一堆东西就可以用了

如图所示


Python实现什么值得买网站的定时检测爬虫

29 回复

不用这么麻烦。 smzdm 自己提供 rss feed 的,你用 rss2email 加上过滤器就行了。


我来帮你实现一个定时检测“什么值得买”网站优惠信息的爬虫。这个爬虫会定时抓取最新优惠,并保存到本地文件。

import requests
from bs4 import BeautifulSoup
import schedule
import time
import json
from datetime import datetime
import logging

class SMZDM_Crawler:
    def __init__(self):
        self.base_url = "https://www.smzdm.com"
        self.headers = {
            'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36'
        }
        self.setup_logging()
        
    def setup_logging(self):
        logging.basicConfig(
            level=logging.INFO,
            format='%(asctime)s - %(levelname)s - %(message)s',
            handlers=[
                logging.FileHandler('smzdm_crawler.log'),
                logging.StreamHandler()
            ]
        )
        self.logger = logging.getLogger(__name__)
    
    def fetch_hot_deals(self):
        """抓取热门优惠信息"""
        try:
            response = requests.get(self.base_url + "/hot/", headers=self.headers, timeout=10)
            response.raise_for_status()
            soup = BeautifulSoup(response.text, 'html.parser')
            
            deals = []
            items = soup.select('.feed-hot-card')
            
            for item in items[:20]:  # 限制前20条
                deal = {}
                
                # 提取标题
                title_elem = item.select_one('.z-feed-title a')
                if title_elem:
                    deal['title'] = title_elem.get_text(strip=True)
                    deal['link'] = title_elem.get('href', '')
                
                # 提取价格
                price_elem = item.select_one('.z-highlight')
                deal['price'] = price_elem.get_text(strip=True) if price_elem else '未知'
                
                # 提取优惠描述
                desc_elem = item.select_one('.z-feed-desc')
                deal['description'] = desc_elem.get_text(strip=True) if desc_elem else ''
                
                # 提取时间
                time_elem = item.select_one('.feed-block-extras')
                deal['time'] = time_elem.get_text(strip=True) if time_elem else ''
                
                # 提取值率
                worth_elem = item.select_one('.z-icon-worth')
                deal['worth_rate'] = '值得买' if worth_elem else '普通'
                
                if deal.get('title'):
                    deal['crawl_time'] = datetime.now().strftime('%Y-%m-%d %H:%M:%S')
                    deals.append(deal)
            
            return deals
            
        except Exception as e:
            self.logger.error(f"抓取失败: {e}")
            return []
    
    def save_to_json(self, deals, filename=None):
        """保存数据到JSON文件"""
        if not filename:
            filename = f"smzdm_deals_{datetime.now().strftime('%Y%m%d_%H%M%S')}.json"
        
        try:
            with open(filename, 'w', encoding='utf-8') as f:
                json.dump(deals, f, ensure_ascii=False, indent=2)
            self.logger.info(f"数据已保存到 {filename}")
            return True
        except Exception as e:
            self.logger.error(f"保存失败: {e}")
            return False
    
    def run_crawler(self):
        """执行一次完整的爬取任务"""
        self.logger.info("开始执行爬取任务...")
        deals = self.fetch_hot_deals()
        
        if deals:
            self.save_to_json(deals)
            self.logger.info(f"成功抓取 {len(deals)} 条优惠信息")
            # 打印前3条结果
            for i, deal in enumerate(deals[:3], 1):
                print(f"{i}. {deal['title']}")
                print(f"   价格: {deal['price']} | 值率: {deal['worth_rate']}")
                print(f"   时间: {deal['time']}")
                print()
        else:
            self.logger.warning("未抓取到任何优惠信息")
    
    def schedule_crawler(self, interval_minutes=30):
        """设置定时任务"""
        self.logger.info(f"定时爬虫已启动,每 {interval_minutes} 分钟执行一次")
        
        # 立即执行一次
        self.run_crawler()
        
        # 设置定时任务
        schedule.every(interval_minutes).minutes.do(self.run_crawler)
        
        while True:
            schedule.run_pending()
            time.sleep(60)  # 每分钟检查一次

def main():
    crawler = SMZDM_Crawler()
    
    # 使用方式1:单次执行
    # crawler.run_crawler()
    
    # 使用方式2:定时执行(每30分钟)
    crawler.schedule_crawler(interval_minutes=30)

if __name__ == "__main__":
    main()

代码说明:

  1. 核心功能:

    • 使用requests和BeautifulSoup抓取"什么值得买"热门优惠页面
    • 提取商品标题、价格、描述、发布时间和值率信息
    • 自动保存为JSON文件,文件名包含时间戳
  2. 定时功能:

    • 使用schedule库实现定时任务
    • 可配置执行间隔(默认30分钟)
    • 首次启动立即执行一次
  3. 日志记录:

    • 同时输出到控制台和日志文件
    • 记录爬取时间、成功条数等信息
  4. 使用方式:

    • 直接运行:python smzdm_crawler.py
    • 修改interval_minutes参数调整检测频率
    • 注释掉定时部分,使用run_crawler()单次执行

依赖安装:

pip install requests beautifulsoup4 schedule

注意事项:

  • 遵守网站robots.txt规则
  • 适当设置请求间隔,避免对服务器造成压力
  • 网站结构可能变化,需要定期维护选择器

这个爬虫会定时检测最新优惠,适合用来监控心仪商品的降价信息。

没想到 rss 还能干这事。谢谢了

之前我也写过一个,出现关键词自动给自己发短信
不过兄弟我得告诉你个悲壮的事。。张大妈客户端有这个功能了。。

你说那个关注么。。那个玩意经常刷不出来

= =我这儿没啊,挺好用的,之前电动牙刷关注了给我推了个接近历低的活动。。

好像自从上次改版后关注特别难用,只能关注特定商品或者特定商城,不如原来的分类关注好了,我一般只关注买书方面,但关注中亚会推别的商品,好难用

开始写爬虫之前要关注两个事情,网站是不是有 API ,以及是否有 RSS 订阅!

这个就是用的网站的 API 拿到的直接是 JSON 数据

兄弟 加油,我最近也想做一个… 张大妈自带的推送简直太垃圾了,甚至说废品。
楼上有说 rss 订阅的,其实远远不够符合需求,有些时候我们要的并不是某一个特定商品,而是某一类商品,然后在从中挑选比较热门的,怎么评判。没有大数据的时候只能依靠 评论数 以及点赞的比例。
ps… api 在哪,我怎么没找到?

等便宜 所花费的时间和精力 都可以赚回来了吧。

划不来

看一眼代码 抓到的包里有一个获取当前最新的 20 条信息的 API ,不算是官方提供的 API ,但是确实可以直接拿来用

是的 这个只是玩票性质的 刚需的商品肯定等不了……

http://www.zhiribao.com 可以 app 微信 邮件推送,值得买的评论都可以在那里看,还要自己写啥?

采集的?


有没有这样一个网站, 购物指导性质的,例如买个台灯,直接推荐 5 个最好的,并且分析优缺点

评论好像没采到吧。 采这个 流量如何

十分钟后才开始采集当前内容的评论,你去翻之前的内容。 V2EX 回复了一段点发送空白了

色魔张大妈 app 支持 添加关键字 推送

等我手下的先忙完了… 再管这个 233 到时候如果找不到接口了,估计还要有劳楼主。

有个人有微信的公众号接口。可以跟 github 绑了 之后 拿到 key 就可以调用了。微信提醒 比邮箱要快

……谢谢 这个看起来蛮好用

涨姿势了

等干完活空了看下

想问下 费钱费在哪里?
推送 QQ 怎么做的?

费钱的意思就是买的多呗……推送 QQ 基本都是基于 WebQQ 的方案,你可以看看酷 Q 的接口

嗯 之前用 webqq 不太好用 现在用酷 q 缺点是 windows only

几年前写过一个类似东西,不过是监测二手东的

现在抓到的包有签名算法,api 不能直接用了,得逆向复现签名算法

回到顶部