news 2026/2/11 3:36:40

实时监控 1688 商品价格变化的爬虫系统实现

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
实时监控 1688 商品价格变化的爬虫系统实现

在电商运营、市场调研以及个人网购决策中,商品价格的实时监控具有重要的价值。1688 作为国内头部的批发电商平台,其商品价格的波动直接反映了供应链、市场需求的变化。本文将详细介绍如何搭建一套实时监控 1688 商品价格变化的爬虫系统,从技术选型、核心逻辑实现到数据存储与告警机制,完整呈现系统的构建过程。

一、技术选型与系统架构

(一)技术栈选择

爬虫系统的核心需求是页面解析定时任务执行数据存储价格变化告警,结合 1688 的页面特性,我们选择以下技术栈:

  1. 编程语言:Python。Python 拥有丰富的爬虫库(如 Requests、BeautifulSoup、Selenium)和数据处理库,开发效率高。
  2. 请求库:Requests(处理常规接口请求)+ Selenium(处理动态渲染页面)。1688 部分商品页面采用 JavaScript 动态渲染,单纯的 Requests 无法获取完整数据,需结合 Selenium 模拟浏览器行为。
  3. 解析库:BeautifulSoup4。用于解析 HTML 页面,提取商品名称、价格、规格等核心信息。
  4. 定时任务:APScheduler。实现定时爬取商品价格的功能,支持灵活的时间配置(如每隔 1 小时爬取一次)。
  5. 数据存储:SQLite。轻量级关系型数据库,无需额外部署,适合小型监控系统;若需扩容,可无缝迁移至 MySQL。
  6. 告警机制:SMTP 协议。当价格发生变化时,通过邮件发送告警信息。

(二)系统架构

系统分为四个核心模块:

  1. 爬虫模块:负责向 1688 发送请求,获取商品页面并解析关键数据。
  2. 定时任务模块:触发爬虫模块按指定频率执行爬取操作。
  3. 数据存储模块:存储商品的历史价格数据和基础信息。
  4. 告警模块:对比当前价格与历史价格,若发生变化则触发告警。

二、环境搭建

(一)数据库表设计

我们创建两张表:<font style="color:rgba(0, 0, 0, 0.85) !important;">goods_info</font>(存储商品基础信息)和<font style="color:rgba(0, 0, 0, 0.85) !important;">price_record</font>(存储商品价格记录)。

python

运行

importsqlite3# 初始化数据库definit_db():conn=sqlite3.connect('1688_price_monitor.db')cursor=conn.cursor()# 创建商品信息表cursor.execute(''' CREATE TABLE IF NOT EXISTS goods_info ( goods_id TEXT PRIMARY KEY, goods_name TEXT, goods_url TEXT UNIQUE, create_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP ) ''')# 创建价格记录表cursor.execute(''' CREATE TABLE IF NOT EXISTS price_record ( id INTEGER PRIMARY KEY AUTOINCREMENT, goods_id TEXT, price FLOAT, crawl_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP, FOREIGN KEY (goods_id) REFERENCES goods_info (goods_id) ) ''')conn.commit()conn.close()if__name__=='__main__':init_db()

(二)爬虫模块实现

1688 商品链接格式通常为<font style="color:rgba(0, 0, 0, 0.85) !important;">https://detail.1688.com/offer/[商品ID].html</font>,我们需要解析页面中的商品名称、价格信息。对于动态渲染的页面,使用 Selenium 加载页面后再解析。

python

运行

importrequestsfrombs4importBeautifulSoupfromseleniumimportwebdriverfromselenium.webdriver.chrome.optionsimportOptionsimporttime# 配置Chrome无头模式,避免弹出浏览器窗口defget_chrome_driver():chrome_options=Options()chrome_options.add_argument('--headless')chrome_options.add_argument('--no-sandbox')chrome_options.add_argument('--disable-dev-shm-usage')driver=webdriver.Chrome(options=chrome_options)returndriver# 解析商品信息defparse_goods_info(goods_url):try:# 初始化驱动driver=get_chrome_driver()driver.get(goods_url)# 等待页面加载完成time.sleep(3)page_source=driver.page_source soup=BeautifulSoup(page_source,'html.parser')# 提取商品ID(从URL中截取)goods_id=goods_url.split('/')[-1].replace('.html','')# 提取商品名称(不同页面可能有不同的class,需根据实际情况调整)goods_name=soup.find('h1',class_='title').get_text().strip()ifsoup.find('h1',class_='title')else'未知名称'# 提取商品价格(1688价格可能存在多个规格,此处提取最低价格)price_tag=soup.find('span',class_='price')price=float(price_tag.get_text().strip())ifprice_tagelse0.0driver.quit()return{'goods_id':goods_id,'goods_name':goods_name,'goods_url':goods_url,'price':price}exceptExceptionase:print(f'解析商品信息失败:{e}')returnNone

(三)数据存储与价格对比

将爬取的商品信息存入数据库,并对比历史价格,判断是否发生变化。

python

运行

importsqlite3fromdatetimeimportdatetime# 插入商品基础信息definsert_goods_info(goods_data):conn=sqlite3.connect('1688_price_monitor.db')cursor=conn.cursor()try:cursor.execute(''' INSERT OR IGNORE INTO goods_info (goods_id, goods_name, goods_url) VALUES (?, ?, ?) ''',(goods_data['goods_id'],goods_data['goods_name'],goods_data['goods_url']))conn.commit()exceptExceptionase:print(f'插入商品信息失败:{e}')finally:conn.close()# 插入价格记录并对比历史价格definsert_price_record(goods_data):conn=sqlite3.connect('1688_price_monitor.db')cursor=conn.cursor()try:# 获取最新的历史价格cursor.execute(''' SELECT price FROM price_record WHERE goods_id = ? ORDER BY crawl_time DESC LIMIT 1 ''',(goods_data['goods_id'],))history_price=cursor.fetchone()# 插入新价格记录cursor.execute(''' INSERT INTO price_record (goods_id, price) VALUES (?, ?) ''',(goods_data['goods_id'],goods_data['price']))conn.commit()# 判断价格是否变化ifhistory_priceisNone:# 首次爬取,无历史价格return(False,0.0,goods_data['price'])else:history_price=history_price[0]ifabs(goods_data['price']-history_price)>0.01:# 价格变化阈值为0.01元return(True,history_price,goods_data['price'])else:return(False,history_price,goods_data['price'])exceptExceptionase:print(f'插入价格记录失败:{e}')return(False,0.0,0.0)finally:conn.close()

(四)告警模块实现

当价格发生变化时,通过邮件发送告警信息。

python

运行

importsmtplibfromemail.mime.textimportMIMETextfromemail.headerimportHeader# 邮件告警配置SMTP_SERVER='smtp.qq.com'# 以QQ邮箱为例SMTP_PORT=587SEND_EMAIL='your_email@qq.com'# 发件人邮箱SEND_PASSWORD='your_email_password'# 邮箱授权码RECEIVE_EMAIL='receive_email@163.com'# 收件人邮箱# 发送价格告警邮件defsend_price_alert(goods_data,history_price,current_price):try:msg=MIMEText(f'商品:{goods_data["goods_name"]}\n'f'商品链接:{goods_data["goods_url"]}\n'f'历史价格:{history_price}元\n'f'当前价格:{current_price}元\n'f'价格变化时间:{datetime.now().strftime("%Y-%m-%d %H:%M:%S")}','plain','utf-8')msg['From']=Header('1688价格监控系统','utf-8')msg['To']=Header('用户','utf-8')msg['Subject']=Header(f'【价格变化告警】{goods_data["goods_name"]}','utf-8')# 连接SMTP服务器并发送邮件server=smtplib.SMTP(SMTP_SERVER,SMTP_PORT)server.starttls()server.login(SEND_EMAIL,SEND_PASSWORD)server.sendmail(SEND_EMAIL,RECEIVE_EMAIL,msg.as_string())server.quit()print('告警邮件发送成功')exceptExceptionase:print(f'发送告警邮件失败:{e}')

(五)定时任务模块

使用 APScheduler 实现定时爬取,例如每隔 1 小时爬取一次指定商品。

python

运行

fromapscheduler.schedulers.blockingimportBlockingScheduler# 核心监控任务defmonitor_task(goods_url):# 1. 爬取商品信息goods_data=parse_goods_info(goods_url)ifnotgoods_data:return# 2. 插入商品基础信息insert_goods_info(goods_data)# 3. 插入价格记录并对比price_changed,history_price,current_price=insert_price_record(goods_data)# 4. 价格变化则发送告警ifprice_changed:send_price_alert(goods_data,history_price,current_price)else:print(f'商品{goods_data["goods_name"]}价格未变化,当前价格:{current_price}元')if__name__=='__main__':# 初始化数据库init_db()# 待监控的商品链接target_goods_url='https://detail.1688.com/offer/123456789.html'# 替换为实际商品链接# 创建调度器scheduler=BlockingScheduler()# 添加定时任务,每隔1小时执行一次(cron表达式:0 */1 * * *)scheduler.add_job(monitor_task,'cron',hour='*/1',args=[target_goods_url])print('1688价格监控系统已启动,每隔1小时执行一次爬取任务...')try:scheduler.start()exceptKeyboardInterrupt:print('系统已停止')

四、系统优化与注意事项

(一)反爬机制应对

1688 具有反爬机制,直接频繁爬取可能会被封 IP,因此需要做以下优化:

  1. 添加请求头:在 Requests 或 Selenium 中添加 User-Agent、Referer 等请求头,模拟浏览器请求。
  2. 设置随机延迟:爬取任务之间设置随机的时间间隔,避免固定频率请求。
  3. 使用代理 IP:对于大规模监控,可使用代理 IP 池轮换 IP,降低被封风险。推荐使用亿牛云代理
  4. 限制爬取频率:根据 1688 的 robots 协议,合理设置爬取频率,避免对服务器造成压力。

(二)页面解析适配

1688 的页面结构可能会更新,导致解析失败。因此,在代码中需要增加异常处理,并定期检查页面结构的变化,及时调整解析规则。

(三)数据扩容

当监控的商品数量增多时,SQLite 的性能可能不足,可将数据库迁移至 MySQL,并添加索引优化查询速度。同时,可引入 Redis 缓存常用的商品信息,减少数据库访问压力。

五、总结

本文搭建的 1688 商品价格监控系统,通过 Python 实现了爬虫、数据存储、定时任务和告警的全流程功能。该系统可满足个人或小型团队的价格监控需求,通过简单的扩展(如增加多商品监控、可视化数据展示),还能适配更复杂的场景。在实际使用中,需注意遵守网站的 robots 协议和相关法律法规,避免恶意爬取行为。同时,针对反爬机制和页面结构变化的问题,需要持续优化代码,确保系统的稳定性和可用性。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/2/8 9:25:15

Git Submodule管理子项目:组织复杂AI系统结构

Git Submodule管理子项目&#xff1a;组织复杂AI系统结构 在现代人工智能系统的开发中&#xff0c;一个项目往往不是孤立存在的。它可能依赖于多个外部组件——从模型训练框架到硬件加速库&#xff0c;再到可视化工具和部署脚本。这些模块通常由不同团队维护&#xff0c;拥有各…

作者头像 李华
网站建设 2026/2/6 2:16:39

LangChain实战快速入门笔记(三)--LangChain使用之Memory

LangChain实战快速入门笔记&#xff08;三&#xff09;–LangChain使用之Memory 文章目录LangChain实战快速入门笔记&#xff08;三&#xff09;--LangChain使用之Memory一、Memory概述1. &#x1f916;&#xff1a;为什么需要Memory&#xff1f;2. &#x1f916;&#xff1a;什…

作者头像 李华
网站建设 2026/2/2 7:15:41

【Java毕设项目】基于微信小程序的仓储管理系统+SpringBoot后端实现

【Java毕设项目】基于微信小程序的仓储管理系统SpringBoot后端实现 weixin185-基于微信小程序的仓储管理系统SpringBoot后端实现 文章目录【Java毕设项目】基于微信小程序的仓储管理系统SpringBoot后端实现一、内容包括二、运行环境三、需求分析四、功能模块五、效果图展示【部…

作者头像 李华
网站建设 2026/2/8 11:16:05

LobeChat能否实现负载均衡?高可用架构设计建议

LobeChat 能否实现负载均衡&#xff1f;高可用架构设计建议 在企业级 AI 应用日益普及的今天&#xff0c;一个稳定、可扩展的前端交互界面往往决定了用户体验的成败。LobeChat 作为一款现代化、开源的聊天机器人 Web 界面&#xff0c;凭借其优雅的设计和强大的多模型接入能力&a…

作者头像 李华
网站建设 2026/2/7 6:29:52

Locust:可能是一款最被低估的压测工具

01 Locust介绍 开源性能测试工具https://www.locust.io/&#xff0c;基于Python的性能压测工具&#xff0c;使用Python代码来定义用户行为&#xff0c;模拟百万计的并发用户访问。每个测试用户的行为由您定义&#xff0c;并且通过Web UI实时监控聚集过程。 压力发生器作为性能…

作者头像 李华
网站建设 2026/2/3 0:26:30

大模型完全指南:小白入门到程序员精通,一篇就够,必收藏

本文系统介绍了大模型、大语言模型、端到端模型和多模态大模型的概念、工作原理及应用案例。文章详细阐述了大模型训练的基础要素&#xff08;数据、算法、算力&#xff09;和训练流程&#xff0c;解释了各类模型的特点和区别&#xff0c;特别强调了多模态大模型处理和理解不同…

作者头像 李华