欢迎光临
我们一直在努力

Python菜谱爬虫:高效抓取与离线存储实战

1. 项目背景与核心价值

每次想尝试新菜谱时,你是不是也遇到过这些烦恼?打开美食网站要反复刷新页面,广告弹窗不断干扰,网络不稳定时连配料表都加载不全。更糟的是,当你真正站在厨房准备大展身手时,手机屏幕沾上面粉后怎么划都失灵…

这个Python菜谱爬虫项目就是为了解决这些痛点而生的。作为一名常年与代码和厨房打交道的开发者,我花了三个月时间迭代了7个版本,最终打磨出这套稳定高效的解决方案。它能从主流美食网站抓取完整菜谱信息(包含菜名、用料清单、详细步骤),并自动生成离线文档。实测下来,完整爬取1000份菜谱只需12分钟,生成的CSV文件在手机、平板、Kindle上都能流畅浏览。

关键优势:数据结构化存储(支持CSV/TXT)、反爬策略自适应、多线程加速采集。即使完全没有爬虫基础,按照本文步骤也能在1小时内完成部署。

2. 环境配置与工具选型

2.1 Python环境搭建

推荐使用Python 3.8+版本,这是目前最稳定的爬虫开发环境。通过以下命令检查版本并安装依赖库:

python –version # 确认版本
pip install requests beautifulsoup4 pandas fake-useragent

  • requests

    :网络请求核心库(比urllib更友好)

  • beautifulsoup4

    :HTML解析神器(简称bs4)

  • pandas

    :数据存储与导出(支持CSV/TXT)

  • fake-useragent

    :伪装浏览器头(防反爬)

避坑提示:Windows用户若遇到SSL错误,需执行

pip install –upgrade certifi

更新证书库。

2.2 开发工具配置

我用VS Code演示操作流程,关键插件如下:

  • Python扩展(必备)
  • Code Runner(一键执行脚本)
  • CSV Viewer(预览生成文件)
  • # 测试环境是否正常
    import requests
    from bs4 import BeautifulSoup
    print("所有依赖库已就绪!")

    3. 目标网站分析与爬虫设计

    3.1 选择合适的美食网站

    经过对比测试,推荐以下两个适合爬取的网站:

  • 下厨房

    (结构清晰,反爬温和)

  • 美食天下

    (菜谱数量庞大)

  • 以"红烧肉"为例,观察下厨房的页面结构:

    • 菜名:

      <h1 class="page-title">

    • 用料:

      <div class="ings">

      下的

      <tr>

      列表

    • 步骤:

      <div class="steps">

      中的

      <li>

      段落

    3.2 爬虫逻辑流程图

    开始 → 获取分类列表 → 进入详情页 → 解析数据 → 存储到CSV → 检查下一页 → 结束

    关键技术点:

    • 使用

      time.sleep(2)

      控制请求频率

    • 随机切换User-Agent头
    • 异常捕获重试机制

    4. 核心代码实现详解

    4.1 网页请求与解析

    def get_recipe(url):
    headers = {'User-Agent': UserAgent().random}
    try:
    response = requests.get(url, headers=headers, timeout=10)
    soup = BeautifulSoup(response.text, 'html.parser')

    # 提取菜名
    title = soup.find('h1', class_='page-title').get_text().strip()

    # 提取用料
    ingredients = []
    for item in soup.select('div.ings tr'):
    name = item.find('td', class_='name').get_text().strip()
    amount = item.find('td', class_='amount').get_text().strip()
    ingredients.append(f"{name} {amount}")

    # 提取步骤
    steps = [step.get_text().strip() for step in soup.select('div.steps li')]

    return {'title': title, 'ingredients': ingredients, 'steps': steps}
    except Exception as e:
    print(f"抓取失败: {url} 错误: {e}")
    return None

    4.2 数据存储模块

    使用pandas保存为CSV和TXT双格式:

    def save_to_file(recipes, filename):
    df = pd.DataFrame(recipes)
    # CSV格式(适合表格查看)
    df.to_csv(f"{filename}.csv", index=False, encoding='utf-8-sig')

    # TXT格式(适合手机阅读)
    with open(f"{filename}.txt", 'w', encoding='utf-8') as f:
    for recipe in recipes:
    f.write(f"【{recipe['title']}】\\n用料:\\n")
    f.write("\\n".join(recipe['ingredients']) + "\\n步骤:\\n")
    f.write("\\n".join(recipe['steps']) + "\\n\\n")

    5. 高级优化技巧

    5.1 突破反爬限制

    实测有效的三种策略:

  • IP轮询

    :使用免费代理池(如github.com/jundiyy/free-proxy-list)
    proxies = {"http": "http://123.123.123.123:8080"}
    requests.get(url, proxies=proxies)

  • 请求间隔随机化

    time.sleep(random.uniform(1, 3))

  • 模拟浏览器行为

    :添加Cookie和Referer头

  • 5.2 多线程加速

    使用

    concurrent.futures

    实现并行抓取:

    from concurrent.futures import ThreadPoolExecutor

    def crawl_category(base_url):
    with ThreadPoolExecutor(max_workers=5) as executor:
    futures = [executor.submit(get_recipe, url) for url in recipe_urls]
    return [f.result() for f in futures if f.result()]

    注意:线程数建议控制在5以内,避免触发网站防护

    6. 成果展示与使用技巧

    6.1 生成文件示例

    CSV文件结构:

    title,ingredients,steps
    红烧肉,"['五花肉 500g','冰糖 20g']","['肉切块焯水','炒糖色…']"

    TXT文件效果:

    【红烧肉】
    用料:
    五花肉 500g
    冰糖 20g
    步骤:
    1. 肉切块焯水…
    2. 炒糖色至琥珀色…

    6.2 手机端优化方案

  • CSV文件

    :用WPS Office打开,启用冻结首行

  • TXT文件

    :推荐使用"静读天下"APP,支持目录跳转

  • Kindle用户

    :用Calibre转换为MOBI格式

  • 7. 常见问题解决方案

    7.1 编码错误处理

    遇到

    UnicodeEncodeError

    时:

    import sys
    sys.setdefaultencoding('utf-8') # Python2需要
    with open('file.txt', 'w', encoding='utf-8-sig') as f: # Python3方案

    7.2 元素定位失效

    当网站改版导致选择器失效时:

  • 使用浏览器开发者工具重新分析(F12)
  • 备用方案:改用XPath定位
    from lxml import etree
    tree = etree.HTML(response.text)
    title = tree.xpath('//h1[@class="new-title"]/text()')[0]

  • 7.3 数据清洗技巧

    去除多余空白和广告文本:

    import re
    clean_text = re.sub(r'\\s+', ' ', raw_text).strip()

    这套系统我已经稳定运行两年,累计爬取超过3万份菜谱。最近新增的智能推荐功能,可以根据已有食材自动匹配菜谱。比如输入"鸡肉、土豆",就能立即生成10种相关做法。这种个性化体验是传统美食APP难以实现的

    赞(0)
    未经允许不得转载:171主机测评 » Python菜谱爬虫:高效抓取与离线存储实战
    分享到: 更多 (0)

    评论 抢沙发

    • 昵称 (必填)
    • 邮箱 (必填)
    • 网址