1. 项目背景与核心思路
去年我在追更一部网络小说时,每次都要手动刷新页面查看更新,这种重复劳动让我萌生了写个爬虫自动抓取的想法。用Python的requests和BeautifulSoup库很快实现了基础功能,但总感觉少了点什么——直到看到AI生成内容的新闻,突然想到:为什么不让爬虫在抓取章节的同时,自动为每章生成吸引人的标题呢?
这个项目的核心价值在于两点:
- 自动化抓取解决了手动追更的繁琐
- AI标题生成让枯燥的章节序号变成有信息量的内容提示
技术栈选择上,我用了:
- 爬虫层:requests + BeautifulSoup(轻量级,适合小说网站结构)
- AI层:HuggingFace的text-generation模型(无需自己训练,直接调用API)
- 调度层:APScheduler(定时抓取新章节)
注意:实际开发中发现,某些小说网站有反爬机制,需要添加随机User-Agent和请求间隔
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 爬虫模块的深度优化
2.1 网页结构解析技巧
不同小说网站的HTML结构差异很大,但都有规律可循。通过Chrome开发者工具分析,发现共性特征:
python复制# 典型的小说章节选择器
chapter_selectors = {
'qidian': 'div.volume-wrap > ul > li > a',
'hongxiu': 'div.volume > ul > li > a',
'17k': 'dl.chapter-list > dd > a'
}
应对动态加载的解决方案:
python复制from selenium import webdriver
def get_dynamic_content(url):
driver = webdriver.Chrome()
driver.get(url)
time.sleep(3) # 等待JS执行
html = driver.page_source
driver.quit()
return html
2.2 反爬对抗实战记录
在连续抓取时遭遇IP封禁,通过以下策略解决:
- 代理IP池搭建:
python复制proxies = {
'http': 'http://user:pass@ip:port',
'https': 'https://user:pass@ip:port'
}
response = requests.get(url, proxies=proxies)
- 请求头随机化:
python复制headers = {
'User-Agent': random.choice(user_agent_list),
'Accept-Language': 'zh-CN,zh;q=0.9'
}
- 请求间隔控制:
python复制time.sleep(random.uniform(1.5, 3.0))
3. AI标题生成器的实现细节
3.1 模型选型对比
测试了三种生成方案:
| 模型类型 | 优点 | 缺点 | 适用场景 |
|---|---|---|---|
| GPT-3.5 | 生成质量高 | 成本高 | 商业级应用 |
| HuggingFace模型 | 免费 | 需要本地部署 | 个人项目 |
| 规则模板 | 速度快 | 创意有限 | 简单场景 |
最终选择HuggingFace的flan-t5-base模型,平衡了效果和资源消耗:
python复制from transformers import pipeline
generator = pipeline('text-generation', model='google/flan-t5-base')
def generate_title(text):
prompt = f"根据以下小说内容生成一个吸引人的章节标题:{text[:200]}"
result = generator(prompt, max_length=30)
return result[0]['generated_text']
3.2 生成效果优化技巧
通过prompt engineering提升生成质量:
- 示例引导:
python复制prompt = """
请模仿以下示例生成小说章节标题:
示例1: 内容:"主角发现神秘玉佩" → 标题:"古玉现世!秘境传承初现端倪"
示例2: 内容:"反派设下陷阱" → 标题:"危机四伏!暗夜杀机悄然降临"
请为以下内容生成标题:{}
""".format(text[:150])
- 风格控制:
python复制prompt += "\n(要求:标题需包含感叹号,长度不超过15字,突出矛盾冲突)"
- 后处理过滤:
python复制def filter_title(title):
banned_words = ['暴力', '色情'] # 过滤敏感词
return not any(word in title for word in banned_words)
4. 系统集成与性能优化
4.1 整体架构设计
mermaid复制graph TD
A[定时触发器] --> B[爬虫模块]
B --> C{新章节?}
C -->|是| D[内容清洗]
D --> E[AI标题生成]
E --> F[本地存储]
F --> G[邮件通知]
C -->|否| H[等待下次触发]
实际代码实现的核心调度逻辑:
python复制from apscheduler.schedulers.blocking import BlockingScheduler
def job():
new_chapters = crawler.check_update()
for chapter in new_chapters:
title = ai_generator.generate(chapter['content'])
db.save_chapter(chapter['url'], title, chapter['content'])
email.send_notification(chapter['url'], title)
scheduler = BlockingScheduler()
scheduler.add_job(job, 'interval', hours=2)
scheduler.start()
4.2 性能瓶颈解决方案
- 异步处理改造:
python复制import asyncio
import aiohttp
async def fetch_chapter(session, url):
async with session.get(url) as response:
return await response.text()
async def main(urls):
async with aiohttp.ClientSession() as session:
tasks = [fetch_chapter(session, url) for url in urls]
return await asyncio.gather(*tasks)
- 缓存机制实现:
python复制from diskcache import Cache
cache = Cache('chapter_cache')
@cache.memoize(expire=3600)
def get_chapter_content(url):
return requests.get(url).text
- 批量生成优化:
python复制def batch_generate_titles(texts):
inputs = tokenizer(texts, return_tensors="pt", padding=True)
outputs = model.generate(**inputs)
return tokenizer.batch_decode(outputs, skip_special_tokens=True)
5. 实际应用中的经验总结
5.1 意想不到的收获
-
标题生成质量超出预期:
- 对战斗场景生成:"剑破苍穹!九重天劫终降临"
- 对感情戏生成:"月下告白:冰山师姐竟红了眼眶"
-
衍生出自动生成章节概要的功能:
python复制summary_prompt = f"用20字概括以下内容:{content[:300]}"
5.2 踩坑警示录
-
法律风险规避:
- 严格遵守robots.txt协议
- 添加版权声明:"生成的标题仅供个人学习使用"
-
模型幻觉问题:
- 出现"主角死亡"等与内容不符的标题
- 解决方案:添加内容校验规则
python复制def validate_title(content, title):
return any(keyword in content for keyword in title.split())
- 资源占用控制:
- 发现内存泄漏:未关闭的selenium驱动
- 修复方案:
python复制try:
driver = webdriver.Chrome()
# do something
finally:
driver.quit()
这个项目给我的最大启示是:技术组合能产生奇妙的化学反应。原本普通的爬虫加上AI能力后,变成了一个让人眼前一亮的小工具。现在每次收到自动生成的章节通知,看到那些比原标题精彩数倍的AI标题,都会有种开盲盒般的惊喜感。
