从爬虫到模型:一个应届生的AI编程初体验

高思涵_全栈
2026-03-13 02:27
阅读 1527

去年秋招拿到offer后,我本以为大四下学期能躺平到入职。结果上周五晚上十点,直属Leader突然在钉钉上@我:“小张,有个紧急需求,下周三前要上线一个竞品价格监控模块,你先搭个原型看看。” 我盯着屏幕愣了三秒——这不就是让我边写爬虫边搞机器学习吗?但谁让我是那个“会点Python”的应届生呢(手动狗头)。

坐标上海,租住在公司隔壁小区,步行十分钟就能到工位。本来想着入职前最后一个月好好打游戏,结果被这个需求拉回了现实。不过也好,正好把之前学的机器学习理论落地一下,毕竟在学校里调参都是用sklearn自带的iris数据集,连真实数据长啥样都不知道。


需求背景:老板想要“智能比价”

事情是这样的:我们团队做的是电商SaaS工具,最近产品经理提了个需求——自动抓取竞品平台的商品价格,然后预测“合理定价区间”。听起来很玄乎,其实就是两个步骤:

  1. 爬虫:定时抓取京东、拼多多等平台的商品页
  2. AI编程:用历史价格数据训练模型,预测未来7天的价格波动

产品经理原话是:“用户输入商品ID,系统就能告诉ta现在是不是抄底价”。我当时内心OS:这需求怕不是看了太多AI宣传视频?但转念一想,这不正是练手的好机会吗?


第一步:爬虫不是你想爬,想爬就能爬

先说爬虫部分。我一开始直接用requests+BeautifulSoup硬刚,结果第二天就被反爬机制教做人——京东直接返回{"error": "403 Forbidden"},拼多多更狠,页面全是加密的JS动态渲染。

踩坑记录

  • 用普通User-Agent被秒封IP
  • 动态加载的内容根本拿不到
  • 商品价格藏在JSON-LD结构化数据里,解析逻辑复杂

后来在GitHub上翻到一个叫selenium-wire的库(感谢开源社区!),配合代理池总算搞定。关键代码如下:

from seleniumwire import webdriver
from fake_useragent import UserAgent
import time
import json

def scrape_jd_price(sku_id):
    # 随机User-Agent防检测
    ua = UserAgent()
    options = webdriver.ChromeOptions()
    options.add_argument(f'--user-agent={ua.random}')
    options.add_argument('--headless')  # 无头模式,省资源
    
    driver = webdriver.Chrome(options=options)
    try:
        url = f"https://item.jd.com/{sku_id}.html"
        driver.get(url)
        time.sleep(3)  # 等待JS加载
        
        # 从页面源码中提取JSON-LD数据
        scripts = driver.find_elements("tag name", "script")
        for script in scripts:
            if "application/ld+json" in script.get_attribute("type"):
                data = json.loads(script.get_attribute("innerHTML"))
                price = data.get("offers", {}).get("price", None)
                return float(price) if price else None
    finally:
        driver.quit()

吐槽:运维同事看到我本地跑ChromeDriver差点报警,说“你这进程占了2G内存,服务器要炸了”。后来改成用Docker容器隔离才过关。


第二步:数据有了,但AI模型怎么选?

爬虫跑了一周,攒了5000多条商品价格记录(主要是手机、耳机这类3C产品)。接下来就是重头戏——AI编程。我翻出《机器学习实战》和吴恩达的课,开始纠结用什么算法。

初期方案:线性回归(天真如我)

第一反应是用线性回归,毕竟最简单。假设价格只和时间相关,画个散点图:

时间戳 价格(元)
1678900000 2999
1678986400 2899
... ...

代码三行搞定:

from sklearn.linear_model import LinearRegression
model = LinearRegression()
model.fit(X_train, y_train)

结果?预测误差高达±300元!因为价格根本不是线性变化的——大促前降价、新品发布后老款跳水,这些非线性规律线性模型完全捕捉不到。

转向树模型:XGBoost真香

被现实毒打后,我转向了集成学习。XGBoost在Kaggle比赛里常年霸榜,对特征工程要求低,特别适合我这种新手。关键改进点:

  1. 特征工程:不只是时间,还加入了:

    • 是否工作日(0/1)
    • 距离最近大促天数(双11、618等)
    • 历史价格波动率(标准差)
    • 竞品平均价格(需要爬多个平台)
  2. 处理时间序列:用滑动窗口构造特征,比如用过去7天的价格预测第8天

# 特征构造示例
def create_features(df):
    df['day_of_week'] = df['timestamp'].dt.dayofweek
    df['is_weekend'] = (df['day_of_week'] >= 5).astype(int)
    df['price_7d_avg'] = df['price'].rolling(window=7).mean()
    df['price_7d_std'] = df['price'].rolling(window=7).std()
    return df.dropna()
  1. 调参玄学:用GridSearchCV暴力搜索,但发现max_depth=5learning_rate=0.1基本够用

最终模型在测试集上MAE(平均绝对误差)降到±85元,对于3000元价位的手机来说,误差<3%,产品经理勉强点头。


模型部署:从Notebook到线上服务

本以为训练完就结束了,结果Leader说:“明天演示,得做成API”。我连夜用Flask搭了个微服务:

from flask import Flask, request, jsonify
import joblib

app = Flask(__name__)
model = joblib.load('price_predictor.pkl')

@app.route('/predict', methods=['POST'])
def predict():
    data = request.json
    sku_id = data['sku_id']
    
    # 1. 实时爬取当前价格
    current_price = scrape_jd_price(sku_id)
    # 2. 构造特征(省略细节)
    features = build_features(sku_id, current_price)
    # 3. 预测
    prediction = model.predict([features])
    
    return jsonify({
        'predicted_price': float(prediction[0]),
        'confidence_interval': [prediction[0]*0.95, prediction[0]*1.05]
    })

血泪教训

  • 模型文件用joblib保存,比pickle快3倍
  • 爬虫加了缓存,避免重复请求(Redis存2小时)
  • 用gunicorn部署,4 worker进程扛住压力测试

上线当天,测试同学疯狂刷接口,QPS飙到200+,服务器CPU瞬间90%。最后加了限流(每IP每分钟10次)才稳住。运维看我的眼神仿佛在说:“应届生真是初生牛犊不怕虎”。


效果对比:不同算法的真实表现

为了说服自己没选错模型,我横向对比了三种算法在相同数据集上的表现:

算法 MAE(元) 训练时间(s) 特征工程难度 适合场景
线性回归 298 0.5 趋势简单、噪声少
随机森林 112 8.2 ⭐⭐ 中等复杂度、可解释性要求高
XGBoost 85 5.7 ⭐⭐ 高精度、大数据量

注:测试环境为MacBook Pro M1, 16GB RAM

结论很明显:XGBoost在精度和速度上取得了最佳平衡。虽然深度学习(比如LSTM)可能更准,但对我这种单机开发、数据量不大的场景,纯属杀鸡用牛刀。


给新人的建议:别被“AI”两个字吓到

折腾完这个项目,我最大的感悟是:机器学习没那么神秘。它本质就是“用数学方法找规律”,而AI编程的核心能力其实是:

  1. 数据清洗能力:80%的时间花在处理脏数据上
  2. 问题定义能力:把业务需求翻译成技术指标(比如“合理价格” → “预测MAE<100元”)
  3. 工程化思维:模型再准,跑不起来等于零

顺便吐槽下:现在有些教程一上来就讲Transformer、BERT,搞得新人以为不会深度学习就out了。其实工作中,XGBoost + 特征工程 能解决80%的问题。我们组去年所有AI项目,70%都用的传统机器学习。


最后:应届生如何快速上手AI编程?

如果你和我一样是CS专业应届生,想在入职前突击AI技能,我的建议是:

  • 别死磕理论:先跑通一个端到端项目(爬虫→训练→部署)
  • 善用现成工具:sklearn、XGBoost、LightGBM文档齐全,API友好
  • 从小数据开始:用Kaggle的Titanic或House Prices入门,别一上来就想搞CV/NLP
  • 重视工程细节:模型保存、API设计、错误处理,这些才是面试加分项

现在我已经把这套代码整理成开源项目(GitHub搜price-predictor-demo),欢迎star。入职前最后两周,我打算用这套框架再做个“租房价格预测”——毕竟在上海,搞懂房价比搞懂算法更重要(笑)。

对了,如果你们公司也在招人,记得内推我啊!(不是)

评论 0

最热最新
暂无评论
高思涵_全栈Lv.1
0
影响力
0
文章
0
粉丝