「编程类软件工具合集」
链接:https://pan.quark.cn/s/0b6102d9a66a
一、为什么选择SQLite存储爬虫数据?
当你在咖啡馆点单时,服务员不会用集装箱给你送咖啡——同理,处理中小规模爬虫数据时,SQLite这个"轻量级数据库"就是最合适的工具。它不需要单独的服务器进程,所有数据存储在单个文件中,却能提供完整的SQL功能支持。
对比其他方案:
MySQL/PostgreSQL:需要安装服务端,配置用户权限,适合企业级应用
MongoDB:文档型数据库,查询效率不如关系型数据库
CSV/JSON文件:缺乏数据类型约束,查询效率低下
SQLite的优势在于:
零配置:下载即用,适合快速原型开发
跨平台:Windows/macOS/Linux全支持
事务支持:保证数据完整性
体积小巧:核心库仅300KB左右
二、环境搭建三步走
- 安装Python环境
确保已安装Python 3.6+版本,通过命令行验证:
python --version
- 安装必要库
使用pip安装爬虫和数据库相关库:
pip install requests beautifulsoup4 sqlite3 fake_useragent
requests:HTTP请求库
beautifulsoup4:HTML解析库
sqlite3:Python内置库,无需单独安装
fake_useragent:生成随机User-Agent
- 准备开发工具
推荐使用VS Code或PyCharm,安装SQLite插件(如SQLite Explorer)方便可视化查看数据。
三、实战:爬取豆瓣电影Top250
- 分析目标网站
打开豆瓣电影Top250页面
每页显示25部电影
URL格式:https://movie.douban.com/top250?start=0(0,25,50...)
每部电影包含:标题、评分、评价人数、引言
- 编写爬虫代码
import requests
from bs4 import BeautifulSoup
import sqlite3
from fake_useragent import UserAgent
def fetch_movie_page(url):
headers = {'User-Agent': UserAgent().random}
try:
response = requests.get(url, headers=headers, timeout=10)
response.raise_for_status()
return response.text
except requests.exceptions.RequestException as e:
print(f"请求失败: {e}")
return None
def parse_movie_info(html):
soup = BeautifulSoup(html, 'html.parser')
movies = []
for item in soup.find_all('div', class_='item'):
title = item.find('span', class_='title').text
rating = item.find('span', class_='rating_num').text
voters = item.find('div', class_='star').find_all('span')[-1].text[:-3]
quote = item.find('span', class_='inq')
quote = quote.text if quote else "无"
movies.append((title, rating, voters, quote))
return movies
def save_to_sqlite(movies):
conn = sqlite3.connect('douban_top250.db')
cursor = conn.cursor()
# 创建表(如果不存在)
cursor.execute('''
CREATE TABLE IF NOT EXISTS movies (
id INTEGER PRIMARY KEY AUTOINCREMENT,
title TEXT NOT NULL,
rating REAL,
voters INTEGER,
quote TEXT
)
''')
# 插入数据
cursor.executemany('''
INSERT INTO movies (title, rating, voters, quote)
VALUES (?, ?, ?, ?)
''', movies)
conn.commit()
conn.close()
print("数据保存成功!")
def main():
base_url = "https://movie.douban.com/top250?start="
all_movies = []
for i in range(0, 250, 25):
url = base_url + str(i)
print(f"正在抓取第{i//25+1}页...")
html = fetch_movie_page(url)
if html:
movies = parse_movie_info(html)
all_movies.extend(movies)
save_to_sqlite(all_movies)
if name == "main":
main()
- 代码解析
请求模块:
使用fake_useragent生成随机User-Agent
设置10秒超时防止长时间等待
异常处理确保程序健壮性
解析模块:
通过CSS选择器定位数据
处理可能缺失的引言字段
返回结构化数据列表
存储模块:
自动创建数据库文件
设计合理的数据表结构
使用事务批量插入数据
四、SQLite进阶技巧 数据查询示例
def query_top_rated():
conn = sqlite3.connect('douban_top250.db')
cursor = conn.cursor()查询评分前10的电影
cursor.execute('''
SELECT title, rating, voters
FROM movies
ORDER BY rating DESC
LIMIT 10
''')for row in cursor.fetchall():
print(f"{row[0]:<30} 评分:{row[1]:<5} 评价人数:{row[2]:>8}")conn.close()
query_top_rated()
- 性能优化建议
批量插入:使用executemany()替代循环插入
索引优化:为常用查询字段创建索引
CREATE INDEX idx_rating ON movies(rating);
连接池:高频访问时考虑使用连接池管理连接
- 数据导出方法
将SQLite数据导出为CSV:
import pandas as pd
def export_to_csv():
conn = sqlite3.connect('douban_top250.db')
df = pd.read_sql_query("SELECT * FROM movies", conn)
df.to_csv('douban_movies.csv', index=False, encoding='utf_8_sig')
conn.close()
print("导出成功!")
export_to_csv()
五、常见问题Q&A
Q1:被网站封IP怎么办?
A:立即启用备用代理池,建议使用住宅代理(如站大爷IP代理),配合每请求更换IP策略。更稳妥的方式是:
设置请求间隔(如随机1-3秒)
使用代理IP轮换
降低并发请求数
模拟正常用户行为(滚动、点击等)
Q2:如何处理反爬机制?
A:常见反爬对策:
携带合法Cookies
设置Referer头
使用Selenium模拟浏览器
解析JavaScript渲染的页面
降低抓取频率
Q3:SQLite适合大规模数据吗?
A:SQLite官方建议单数据库不超过140TB,但实际建议:
小型项目(<10GB):完美选择 中型项目(10GB-100GB):可考虑,但需优化 大型项目(>100GB):建议迁移到MySQL/PostgreSQL
Q4:如何保证数据完整性?
A:使用事务机制:
try:
conn.execute("BEGIN TRANSACTION")
# 执行多个SQL操作
conn.commit()
except:
conn.rollback()
Q5:SQLite支持并发写入吗?
A:支持多进程读取,但写入是串行的。高并发场景建议:
使用WAL模式(Write-Ahead Logging)
PRAGMA journal_mode=WAL;
控制最大连接数
考虑升级数据库系统
六、总结与展望
通过这个实战项目,我们掌握了:
使用Python爬取结构化数据
将数据存储到SQLite数据库
基本的数据查询和导出操作
应对常见反爬策略
SQLite作为轻量级数据库,特别适合:
原型开发
移动应用开发
嵌入式系统
数据分析预处理
进阶方向建议:
学习SQL高级查询
尝试ORM框架(如SQLAlchemy)
研究数据库迁移策略
探索分布式爬虫架构
记住:爬虫开发要遵守robots.txt协议,合理设置抓取频率,尊重网站的数据产权。技术本身无善恶,关键在于如何使用。