Python数据存储爬虫案例?

wen python案例 2

本文目录导读:

  1. 目录导读
  2. 案例背景与需求分析
  3. Python爬虫核心框架选型
  4. 目标数据结构化与清洗
  5. 数据存储方案对比
  6. 完整爬虫存储代码拆解
  7. 常见错误与优化技巧
  8. 问答环节(FAQ)

Python数据存储爬虫案例精讲:从采集到数据库的高效实战

目录导读

  1. 案例背景与需求分析
  2. Python爬虫核心框架选型
  3. 目标数据结构化与清洗
  4. 数据存储方案对比(CSV/MySQL/MongoDB)
  5. 完整爬虫存储代码拆解(附可运行示例)
  6. 常见错误与性能优化技巧
  7. 问答环节(FAQ)

案例背景与需求分析

在当今信息爆炸的互联网环境中,许多程序员面临一个实际问题:如何从网页中抓取公开数据,并持久化存储以供分析? 本文以“爬取某电影网站TOP250榜单”为例,演示从请求发送到数据入库的全流程。
核心挑战:动态页面加载、反爬机制应对、存储格式选择。

Python爬虫核心框架选型

根据搜索引擎最新实践,推荐以下组合:

  • 请求库requests(轻量可靠)或 aiohttp(异步高频)
  • 解析库BeautifulSoup + lxml(适合静态HTML),Selenium(处理JS渲染)
  • 存储库pymysql(关系型)、pymongo(文档型)、内置csv模块

本案例采用 requests + BeautifulSoup + pymysql 组合,兼顾效率与代码可读性。

目标数据结构化与清洗

原始网页数据通常包含:

  • 电影名称(需去除多余空格)
  • 评分(字符串转浮点数)
  • 年份(从“1994 (美国)”中提取数字)
  • 海报链接(补全协议头)

清洗示例

def clean_data(raw):
    return {
        'title': raw['title'].strip(),
        'rating': float(raw['rating']),
        'year': int(raw['year'].split('(')[0]),
        'image': 'https:' + raw['img_url'] if raw['img_url'].startswith('//') else raw['img_url']
    }

数据存储方案对比

存储方式 适用场景 优势 劣势
CSV 小批量、临时分析 无需数据库,Excel直接打开 无索引,并发写入冲突
MySQL 结构化、需联表查询 支持事务,稳定可靠 需预定义表结构,扩展稍慢
MongoDB 字段不固定、快速迭代 灵活JSON文档,水平扩展易 不支持复杂JOIN,内存占用大

本案例选择MySQL,因为电影数据字段固定且后续需要按评分排序查询。

完整爬虫存储代码拆解

以下为可直接运行的简化版代码(省略异常处理细节,可扩展频率限制):

import requests
from bs4 import BeautifulSoup
import pymysql
import re
# 第一步:建立数据库连接
conn = pymysql.connect(host='localhost', user='root', password='yourpass', db='movie_db')
cursor = conn.cursor()
cursor.execute('''CREATE TABLE IF NOT EXISTS movies (
    id INT AUTO_INCREMENT PRIMARY KEY,VARCHAR(255) NOT NULL,
    rating DECIMAL(3,1),
    year INT,
    image_url TEXT
)''')
# 第二步:爬取与解析
headers = {'User-Agent': 'Mozilla/5.0'}
for page in range(10):
    url = f'https://example-movie-site.com/top250?start={page*25}'
    resp = requests.get(url, headers=headers)
    soup = BeautifulSoup(resp.text, 'lxml')
    for item in soup.select('.movie-item'):  # 实际选择器需替换
        title = item.find('span', class_='title').text
        rating = float(item.find('span', class_='rating').text)
        year_str = item.find('span', class_='year').text
        year = int(re.search(r'(\d{4})', year_str).group(1))
        img = item.find('img')['src']
        if img.startswith('//'):
            img = 'https:' + img
        # 第三步:插入数据库
        sql = "INSERT INTO movies (title, rating, year, image_url) VALUES (%s, %s, %s, %s)"
        cursor.execute(sql, (title, rating, year, img))
conn.commit()
cursor.close()
conn.close()
print("数据爬取并存储完成!")

性能提升:使用 executemany() 批量插入,关闭自动提交,每200条commit一次。

常见错误与优化技巧

  • 错误1:连接超时 → 设置 timeout=5,加入 retry 装饰器
  • 错误2:503反爬 → 添加随机延迟 time.sleep(random.uniform(1,3))
  • 优化1:去重 → 先查已存在title,或用 INSERT IGNORE
  • 优化2:增量爬取 → 记录最后爬取ID,下次从该处继续

问答环节(FAQ)

Q1:爬下来的数据为什么乱码?
A:中文网站通常用 utf-8gbk,解析前设置 resp.encoding = resp.apparent_encoding 自动检测。

Q2:MySQL连不上怎么办?
A:检查服务是否启动、端口(默认3306)、用户权限,可用 mysql -u root -p 命令行测试。

Q3:能否直接存到云数据库?
A:可以,只需将host改为云平台内网IP(如腾讯云的CDB),并授权白名单。

Q4:Scrapy框架比手写requests更好吗?
A:Scrapy适合大型分布式爬虫,内置去重、管道、延迟等功能;小项目手写更灵活透明。

Q5:存储大量数据怎样避免重复?
A:创建唯一索引(如电影名称+年份组合),或在插入前用SELECT count(1)校验。


延伸阅读

  • 百度云对象存储COS API文档
  • 阿里云RDS MySQL读写分离配置
  • 学习资源:B站“Python爬虫存储架构”系列视频

(本文综合多个技术博客与官方文档,确保步骤可复现,如需完整代码包,可关注公众号“Python数据挖掘”获取。)

标签: 存储方案

抱歉,评论功能暂时关闭!