
前言
在如今AI编程工具越来越普及的时代,咱们该如何高效搭建一个功能齐全的网络爬虫系统呢?在这篇文章里,我想跟大家分享我使用Qoder这个新兴AI编程助手的经验,带你从零开始构建一个集数据抓取、智能过滤、内容清洗和实时监控于一体的全能爬虫系统。
项目概览
这个爬虫系统主要用来抓取矿山、自然资源和地质等政府网站的信息,具备以下几个核心特点:
- 智能关键词过滤:使用93个专业关键词,设定多层次的权重评分。
- 高效去重机制:通过SQLite数据库来管理,支持任务的断点续传。
- 随机抓取功能:采用真正的随机算法,避免被识别出抓取模式。
- 实时Web监控:使用Vue.js与FastAPI搭建现代化的用户界面。
- ⚡ JavaScript渲染:通过Selenium支持动态网页内容抓取。
- 智能内容清洗:将HTML转化为Markdown,过滤掉无关信息。
技术架构
核心技术栈
后端:Python + Scrapy + Selenium + SQLite + FastAPI
前端:Vue.js 3 + Bootstrap 5 + Chart.js
工具:html2text + markdownify
系统架构图
graph TB
A[用户接口] --> B[爬虫控制器]
B --> C[Scrapy引擎]
C --> D[下载中间件]
D --> E[JavaScript渲染]
E --> F[响应处理]
F --> G[内容过滤器]
G --> H[数据管道]
H --> I[SQLite数据库]
H --> J[HTML文件存储]
J --> K[内容清洗器]
K --> L[Markdown输出]
M[Web监控界面] --> N[FastAPI后端]
N --> I
N --> O[实时统计]
O --> P[图表展示]
核心功能实现
1. 智能关键词过滤系统
这是整个系统的一大亮点。我们设计了一套多层次的内容评分机制:
def is_content_relevant(self, html_content, url):
"""检查页面内容是否与矿山、自然资源、地质相关"""
# 提取不同权重的文本内容
title_text = self.extract_title(soup) * 5 # 标题权重5倍
meta_text = self.extract_meta(soup) * 3 # meta权重3倍
heading_text = self.extract_headings(soup) * 2 # 标题权重2倍
page_text = self.extract_content(soup) # 正文权重1倍
# 加权内容评分
weighted_content = title_text + meta_text + heading_text + page_text
# 关键词匹配和计分
matched_keywords = []
keyword_score = 0
for keyword in self.target_keywords:
if keyword in weighted_content:
matched_keywords.append(keyword)
keyword_score += weighted_content.count(keyword)
# 判断标准:匹配关键词≥2个或总权重≥5分
return len(matched_keywords) >= 2 or keyword_score >= 5
关键词库设计:
- 矿山相关:矿山、矿业、采矿、矿井、矿物等。
- 资源相关:自然资源、国土资源、水资源、森林资源等。
- 地质相关:地质勘探、调查、岩石、地层、断层等。
- 机构术语:自然资源部、地质调查局、勘察设计等。
2. 高效去重与状态管理
我们利用SQLite数据库来精确管理URL状态:
class UrlDatabase:
def __init__(self):
self.conn = sqlite3.connect('spider_urls.db')
self.setup_database()
def add_url(self, url, source_url=None, depth=0):
"""添加URL到待抓取队列"""
normalized_url = normalize_url(url)
cursor = self.conn.cursor()
cursor.execute('''
INSERT OR IGNORE INTO urls
(url, normalized_url, source_url, depth, status, created_at)
VALUES (?, ?, ?, ?, 'pending', datetime('now'))
''', (url, normalized_url, source_url, depth))
return cursor.rowcount > 0
def get_random_pending_urls(self, limit=10):
"""随机获取待抓取URL"""
cursor = self.conn.cursor()
cursor.execute('''
SELECT url, depth FROM urls
WHERE status = 'pending'
ORDER BY RANDOM()
LIMIT ?
''', (limit,))
return cursor.fetchall()
数据库设计亮点:
- 通过normalized_url字段避免因参数顺序引起的重复。
- 支持断点续传,系统重启后可以继续未完成的任务。
- 记录抓取状态与时间戳,方便后续分析与调试。
3. 动态网页渲染支持
现代网站普遍使用JavaScript,传统爬虫常常难以应对。我们集成了Selenium:
class JavaScriptMiddleware:
def __init__(self):
self.driver_pool = DriverPool(max_drivers=3)
def process_request(self, request, spider):
if request.meta.get('render_js'):
driver = self.driver_pool.get_driver()
try:
driver.get(request.url)
# 等待页面加载完成
WebDriverWait(driver, 10).until(
EC.presence_of_element_located((By.TAG_NAME, "body"))
)
# 执行页面滚动,触发懒加载
driver.execute_script("window.scrollTo(0, document.body.scrollHeight);")
time.sleep(2)
html_content = driver.page_source
return HtmlResponse(url=request.url, body=html_content, encoding='utf-8')
finally:
self.driver_pool.return_driver(driver)
4. 智能内容清洗系统
这是项目里的另一个创新。原始的HTML含有大量无关内容,我们开发了一种智能清洗算法:
class HTMLCleaner:
def __init__(self, min_content_length=200):
self.min_content_length = min_content_length
# 导航菜单识别模式
self.nav_patterns = [
r'首页[s|>]*', r'当前位置[s::]*', r'您现在的位置[s::]*',
r'导航[s::]*', r'面包屑[s::]*', r'>>s*', r'更多[>>]*'
]
# 需要移除的标签和类名
self.unwanted_tags = ['nav', 'header', 'footer', 'aside', 'script']
self.unwanted_classes = ['navigation', 'sidebar', 'ad', 'social']
def assess_content_quality(self, text):
"""五级质量评分系统"""
# 1. 长度得分(20分)
length_score = min(20, len(text) / 50)
# 2. 结构完整性(20分)
structure_score = self.calculate_structure_score(text)
# 3. 实质内容比例(30分)
content_ratio = self.calculate_content_ratio(text)
content_score = content_ratio * 30
# 4. 导航内容过滤(20分)
nav_score = self.calculate_nav_filter_score(text)
# 5. 领域相关性(10分)
domain_score = self.calculate_domain_relevance(text)
total_score = length_score + structure_score + content_score + nav_score + domain_score
return total_score, {
'length': length_score,
'structure': structure_score,
'content': content_score,
'nav_filter': nav_score,
'domain': domain_score
}
质量控制标准:
- 最小内容长度:200字符。
- 质量评分阈值:40分(满分100分)。
- 自动过滤导航和无关内容。
- 智能识别并提取主要内容区域。
5. 实时Web监控界面
我们使用FastAPI和Vue.js构建了一个现代化监控界面:
from fastapi import FastAPI, WebSocket
from fastapi.staticfiles import StaticFiles
import asyncio
app = FastAPI(title="爬虫监控系统")
@app.websocket("/ws")
async def websocket_endpoint(websocket: WebSocket):
await websocket.accept()
try:
while True:
# 实时推送统计数据
stats = get_spider_stats()
await websocket.send_json(stats)
await asyncio.sleep(1)
except WebSocketDisconnect:
pass
@app.get("/api/stats")
async def get_statistics():
"""获取抓取统计信息"""
db = UrlDatabase()
return {
'total_urls': db.get_total_count(),
'pending': db.get_pending_count(),
'completed': db.get_completed_count(),
'failed': db.get_failed_count(),
'success_rate': db.get_success_rate()
}
监控界面特性:
- 实时数据更新(WebSocket推送)。
- 可视化图表展示(Chart.js)。
- 监控爬虫状态。
- 查看错误日志。
- 手动控制启停。
项目结构与最佳实践
目录组织
spider/
├── spider.py # 主启动脚本
├── run_spider.py # 核心运行脚本
├── webspider/ # 爬虫源码包
│ ├── spiders/webspider.py # 主爬虫类
│ ├── database.py # 数据库管理
│ ├── middlewares.py # 中间件
│ └── pipelines.py # 数据管道
├── frontend/ # Web监控界面
│ ├── main.py # FastAPI服务器
│ └── templates/index.html # Vue.js前端
├── scripts/ # 工具脚本
│ ├── html_cleaner.py # HTML清洗工具
│ ├── clean_duplicates.py # 重复文件清理
│ └── start_monitor.py # 监控启动脚本
├── tests/ # 测试文件
├── docs/ # 文档目录
├── webpages/ # 原始HTML存储
├── mdpages/ # 清洗后Markdown
└── spider_urls.db # SQLite数据库
配置管理
通过Scrapy的settings.py进行统一配置:
# 基础设置
BOT_NAME = 'webspider'
ROBOTSTXT_OBEY = False
CONCURRENT_REQUESTS = 16
DOWNLOAD_DELAY = 1
RANDOMIZE_DOWNLOAD_DELAY = 0.5
# 中间件配置
DOWNLOADER_MIDDLEWARES = {
'webspider.middlewares.UrlFilterMiddleware': 300,
'webspider.middlewares.JavaScriptMiddleware': 400,
'webspider.middlewares.RandomUserAgentMiddleware': 500,
}
# 管道配置
ITEM_PIPELINES = {
'webspider.pipelines.DuplicatesPipeline': 300,
'webspider.pipelines.HtmlStoragePipeline': 400,
'webspider.pipelines.DatabasePipeline': 500,
}
# JavaScript渲染设置
SELENIUM_DRIVER_NAME = 'chrome'
SELENIUM_DRIVER_EXECUTABLE_PATH = None # 自动检测
SELENIUM_DRIVER_ARGUMENTS = ['--headless', '--no-sandbox']
性能优化与扩展性
1. 性能优化策略
并发控制:
- 合理设置并发请求数(16个)。
- 随机下载延迟(0.5-1.5秒)。
- 连接池复用。
- 异步I/O操作。
内存管理:
- 及时释放Selenium WebDriver。
- 使用数据库连接池。
- 大文件流式处理。
- 优化垃圾回收。
缓存机制:
- HTTP响应缓存。
- DNS解析缓存。
- 静态资源CDN。
- 数据库查询缓存。
2. 扩展性设计
模块化架构:每个功能模块独立设计,方便扩展和维护:
# 插件式过滤器
class ContentFilter:
def __init__(self):
self.filters = [
KeywordFilter(),
LengthFilter(),
QualityFilter(),
DomainFilter()
]
def apply_filters(self, content):
for filter_instance in self.filters:
if not filter_instance.accept(content):
return False
return True
# 可配置的存储后端
class StorageBackend:
def get_backend(self, backend_type):
backends = {
'file': FileStorage(),
'database': DatabaseStorage(),
'cloud': CloudStorage()
}
return backends.get(backend_type, FileStorage())
实际效果与数据
抓取效果统计
经过实际测试,系统在处理政府网站时表现得非常出色:
- 数据源:自然资源部、各省地质局等官方网站。
- 抓取网页:693个HTML文件。
- 质量过滤后:92个高质量Markdown文件。
- 过滤效率:86.7%的噪声内容被成功过滤。
- 平均处理速度:每个页面约200毫秒。
- 内容质量评分:平均得分65分(满分100分)。
内容清洗效果对比
处理前(原始HTML):
江苏省困难退役军人帮扶援助工作实施办法
为进一步推进我省困难退役军人帮扶援助工作...
处理后(清洗的Markdown):
# 江苏省困难退役军人帮扶援助工作实施办法
为进一步推进我省困难退役军人帮扶援助工作规范化、制度化建设,根据《中华人民共和国退役军人保障法》...
## 第一章 总则
第一条 根据《中华人民共和国退役军人保障法》等法律法规规定...
可以看到,系统成功去掉了导航、侧边栏、页脚等无关内容,保留了重要的政策文件信息。
开发心得与最佳实践
1. Qoder使用体验
优势:
- 智能代码生成:能够快速生成符合需求的高质量代码框架。
- 问题诊断能力:可以精准识别和修复代码中的问题。
- 文档生成:自动生成详细的技术文档和使用说明。
- 最佳实践建议:提供专业的架构设计和优化建议。
协作模式:
- 我负责需求分析和架构设计。
- Qoder则负责代码实现和问题修复。
- 通过不断迭代优化,逐步完善功能。
2. 开发过程中的挑战
技术挑战:
- JavaScript渲染:一些政府网站采用复杂的JavaScript框架。
- 反爬机制:需要模拟真实用户的行为。
- 内容识别:准确区分有价值的内容和噪声信息。
- 性能平衡:在质量和效率之间寻找合适的平衡点。
解决方案:
- 多层渲染策略:优先采用静态抓取,必要时启用JS渲染。
- 智能延迟:随机请求间隔,模拟人工浏览。
- 机器学习辅助:结合规则与模式识别来提高效率。
- 分层处理:优先处理关键内容,批量处理以降低延迟。
3. 项目管理经验
版本控制:
- 功能模块独立开发。
- 详细记录每次提交的说明。
- 实施分支管理策略。
测试驱动:
- 对核心功能进行单元测试。
- 通过集成测试验证整体流程。
- 进行性能测试以确保系统稳定。
文档维护:
- API文档自动生成。
- 用户手册保持实时更新。
- 记录开发过程中的决策与反思。
未来规划
短期优化(1-2个月)
- 智能去重增强:基于内容相似度的去重算法。
- 分布式部署:支持多台机器协同工作。
- 数据可视化:提供更丰富的统计图表和分析功能。
- API接口:提供RESTful API供第三方调用。
长期发展(3-6个月)
- 机器学习集成:
- 智能内容分类。
- 自动提取关键词。
- 识别网站结构。
- 云原生部署:
- 使用Docker进行容器化。
- 利用Kubernetes进行编排。
- 构建微服务架构。
- 数据处理增强:
- 实时数据流处理。
- 集成大数据分析功能。
- 构建知识图谱。
总结
通过这个项目,我深刻感受到AI编程助手在复杂系统开发中的巨大价值。Qoder不仅提升了开发效率,更提供了专业的技术指导和最佳实践建议。
关键收获:
- AI协作开发模式:人机合作能够显著提升开发质量和效率。
- 系统化思维:从需求分析到部署运维的全链路考虑。
- 质量与效率平衡:在功能完备性与系统性能中找到最佳平衡。
- 持续优化精神:系统设计要考虑长期演进与扩展。
这个爬虫系统已经在实际应用中发挥了重要作用,成功抓取和清洗了大量政府网站的高质量内容。如果你也在开发类似的数据采集系统,希望我的经验能对你有所帮助和启发。
欢迎在评论区分享你的爬虫开发经验,或者提问技术问题,我会认真回复每一条评论!
标签:#网络爬虫 #Python #Scrapy #人工智能 #数据采集 #内容清洗 #Qoder #AI编程











我觉得需要强调一下,抓取敏感网站时要注意法律风险,合理合规使用爬虫工具。
前端使用Vue.js和FastAPI搭建,感觉很现代化,能够吸引更多开发者使用。
我自己在使用爬虫时,发现清洗数据是一项很费时的工作。这个系统的智能内容清洗功能是否能大幅提升效率?
我也在尝试搭建爬虫,数据存储用SQLite真心不够灵活,有没有其他推荐?
你有遇到过系统抓取数据时的瓶颈吗?如何解决的?
这篇分享让我对爬虫系统有了更深入的了解,准备尝试一下!