1. 准备工作:搭建Python爬虫环境
第一次接触Python爬虫时,我也被各种专业术语吓到过。但实际操作起来,你会发现这比想象中简单得多。就像组装乐高积木,只要把几个关键部件拼在一起就能运行。我们先来准备最基础的三样工具:
Python解释器:这是运行所有代码的引擎。推荐安装最新稳定版(目前是3.10+),安装时记得勾选"Add Python to PATH"选项,这样能在命令行直接调用python命令。我遇到过不少新手因为漏选这个选项导致后续各种报错。
代码编辑器:VS Code或PyCharm都不错。个人更推荐VS Code,轻量且插件丰富,安装Python扩展后还能直接调试代码。记得配置好中文界面和代码自动补全,这对新手特别友好。
必备库安装:打开命令行(Windows用cmd,Mac用Terminal),逐行执行以下命令:
pip install requests beautifulsoup4 lxml这里requests用来获取网页内容,beautifulsoup4负责解析HTML,lxml则是解析引擎。如果下载速度慢,可以加上国内镜像源:
pip install -i https://pypi.tuna.tsinghua.edu.cn/simple requests beautifulsoup4 lxml提示:遇到SSL证书错误时,可以尝试在命令后添加
--trusted-host pypi.tuna.tsinghua.edu.cn
2. 单章爬取实战:解剖小说网页结构
让我们用《斗破苍穹》第一章做实验(URL示例:https://www.biqg.cc/book/6909/1.html)。打开这个链接后按F12进入开发者工具,你会看到密密麻麻的HTML代码——别慌,我们只需要关注两个关键信息:
- 章节标题:通常在
<h1>标签内,可以用正则表达式r'<h1 class="wap_none">(.*?)</h1>'提取 - 正文内容:往往藏在
<div id="chaptercontent">这样的容器里,用BeautifulSoup的find方法就能精准定位
这是我调试多次后优化的代码模板:
import requests from bs4 import BeautifulSoup import re headers = { 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36' } def get_single_chapter(url): response = requests.get(url, headers=headers) response.encoding = 'utf-8' # 解决中文乱码的关键 soup = BeautifulSoup(response.text, 'html.parser') title = soup.find('h1', class_='wap_none').get_text() content = soup.find('div', id='chaptercontent').get_text('\n') # 清理广告文本 content = content.replace('请收藏本站:https://www.biqg.cc', '') return title, content.strip()实测时会发现几个常见坑点:
- 乱码问题:90%的乱码都是编码设置不对,记得response.encoding要设为utf-8
- 请求被拒:加上User-Agent头模拟浏览器访问
- 内容错位:不同网站结构可能微调,需要适时修改选择器
3. 整本爬取:发现URL规律与自动化
爬完单章后,观察《斗破苍穹》前几章URL:
https://www.biqg.cc/book/6909/1.html https://www.biqg.cc/book/6909/2.html https://www.biqg.cc/book/6909/3.html明显规律是/book/小说ID/章节号.html。利用这个规律,我们可以用for循环批量爬取。但要注意三个优化点:
- 间隔请求:用time.sleep(1)在每个请求间暂停1秒,避免被封IP
- 异常处理:用try-catch包裹请求代码,跳过失效章节
- 进度显示:用print(f'正在爬取第{i}章')让运行过程可视化
改进后的批量爬取代码:
import time def get_full_novel(novel_id, start=1, end=10): with open('斗破苍穹.txt', 'w', encoding='utf-8') as f: for i in range(start, end+1): try: url = f'https://www.biqg.cc/book/{novel_id}/{i}.html' title, content = get_single_chapter(url) f.write(f'\n\n{title}\n\n{content}') print(f'成功爬取: {title}') time.sleep(1) except Exception as e: print(f'第{i}章爬取失败: {str(e)}') continue4. 高级技巧:突破反爬与内容优化
当爬取量较大时,可能会触发网站的反爬机制。根据我的实战经验,这些方法最有效:
- 动态User-Agent:准备多个浏览器标识随机切换
user_agents = [ 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36', 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15' ] headers['User-Agent'] = random.choice(user_agents)- 代理IP池:当IP被封时自动切换(需自行准备代理IP列表)
proxies = { 'http': 'http://123.123.123.123:8888', 'https': 'http://123.123.123.123:8888' } response = requests.get(url, headers=headers, proxies=proxies)- 内容清洗:用正则表达式过滤广告和特殊字符
import re clean_content = re.sub(r'[\u3000\xa0\u200b]+', '', content) # 去除特殊空白符对于超长篇小说(如1000+章),建议分卷保存并添加断点续爬功能。可以记录已爬取的章节号到json文件,下次运行时自动跳过:
import json # 保存进度 progress = {'last_chapter': 50} with open('progress.json', 'w') as f: json.dump(progress, f) # 读取进度 with open('progress.json') as f: progress = json.load(f) start_chapter = progress['last_chapter'] + 1最后分享一个实用技巧:用多线程加速爬取(适合章节数多的小说)。但要注意控制并发数,建议不超过5个线程:
from concurrent.futures import ThreadPoolExecutor def crawl_chapter(chapter_id): # 爬取单章的实现代码... with ThreadPoolExecutor(max_workers=5) as executor: executor.map(crawl_chapter, range(1, 1001))记得小说爬取后要合理使用,尊重版权。这套方法同样适用于其他内容型网站的数据采集,只需调整选择器和URL规则即可。刚开始可能会遇到各种报错,但每个错误都是学习机会——我最初写爬虫时,光是解决SSL验证错误就花了整整一下午,现在回头看那些踩过的坑都成了宝贵经验。