文章目录
前言:为什么选择爬取小说网站?
(认真脸)很多编程新手学爬虫时,最常问的就是:“学完能做什么实际项目?” 作为一个爬虫老司机,我强烈推荐从小说网站练手!相比其他类型网站,小说站点结构更规整(毕竟章节都是线性排列),数据更干净(文字为主),非常适合练级(关键是成就感爆棚啊)!!!
不过要注意(敲黑板):本文仅供技术学习交流,请遵守目标网站的robots协议,切勿用于商业用途!
一、环境准备与工具选择
1.1 基础装备清单
- Python 3.8+(推荐用Anaconda全家桶)
- requests库(网络请求)
- BeautifulSoup4(HTML解析)
- lxml解析器(比默认解析器快3倍)
- fake_useragent(伪装浏览器)
- tqdm(进度条显示)
安装命令(Windows/Mac通用):
pip install requests bs4 lxml fake_useragent tqdm
1.2 开发环境配置小技巧
(踩坑经验)建议在代码开头统一设置编码:
import sys
import io
sys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding='utf-8')
这样可以避免80%的中文乱码问题!
二、实战:从0到1抓取整本小说
2.1 目标网站分析(以某小说网站为例)
用Chrome开发者工具分析页面结构时,重点关注:
- 章节列表的CSS选择器(通常是class="chapter-list"的ul标签)
- 正文内容的HTML标签(常见于div.content或article标签)
- 下一页按钮的XPath路径
(超级重要)一定要检查网站是否使用动态加载!如果发现章节列表是通过AJAX加载的,就需要改用Selenium或分析接口!
2.2 核心代码实现
import requests
from bs4 import BeautifulSoup
from fake_useragent import UserAgent
from tqdm import tqdm
def get_novel_content(base_url):
ua = UserAgent()
headers = {'User-Agent': ua.random}
# 获取章节列表
index_page = requests.get(base_url, headers=headers)
soup = BeautifulSoup(index_page.content, 'lxml')
chapters = soup.select('ul.chapter-list li a')
# 创建进度条
pbar = tqdm(total=len(chapters), desc='抓取进度')
# 遍历所有章节
contents = []
for chapter in chapters:
chap_url = chapter['href']
chap_title = chapter.text.strip()
# 延迟设置(防封必备)
time.sleep(random.uniform(1, 3))
# 获取章节正文
chap_page = requests.get(chap_url, headers=headers)
chap_soup = BeautifulSoup(chap_page.content, 'lxml')
content = chap_soup.find('div', class_='content').text
contents.append(f"## {chap_title}\n{content}\n")
pbar.update(1)
pbar.close()
return contents
2.3 防反爬策略大全
- IP代理池搭建(推荐使用免费代理列表)
proxies = {
'http': 'http://10.10.1.10:3128',
'https': 'http://10.10.1.10:1080',
}
response = requests.get(url, proxies=proxies)
- 请求头随机生成(重点伪装User-Agent和Referer)
headers = {
'User-Agent': UserAgent().random,
'Referer': 'https://www.google.com/',
'Accept-Language': 'zh-CN,zh;q=0.9'
}
- 请求间隔随机化(比固定延迟更有效)
import random
import time
time.sleep(random.randint(1, 5) + random.random())
三、数据存储与可视化
3.1 保存为TXT文件
def save_as_txt(contents, filename):
with open(f'{filename}.txt', 'w', encoding='utf-8') as f:
f.write('\n'.join(contents))
print(f"小说已保存到 {filename}.txt")
3.2 生成词云图(装X必备)
from wordcloud import WordCloud
import jieba
def generate_wordcloud(text):
# 中文分词
seg_list = jieba.cut(text)
word_list = ' '.join(seg_list)
# 生成词云
wc = WordCloud(
font_path='msyh.ttc', # 微软雅黑字体
background_color='white',
width=1000,
height=800
).generate(word_list)
wc.to_file('wordcloud.png')
四、高级技巧:突破反爬限制
4.1 动态加载破解
当遇到JavaScript渲染的页面时,可以使用Selenium模拟浏览器:
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
options = Options()
options.add_argument('--headless') # 无头模式
driver = webdriver.Chrome(options=options)
driver.get(url)
html = driver.page_source
4.2 验证码破解思路
- 使用第三方打码平台(推荐图鉴平台)
- 机器学习训练识别模型(需要大量样本)
- 人工干预法(遇到验证码时暂停程序)
五、法律与道德边界
(严肃提醒)根据《网络安全法》:
- 不得干扰目标网站正常运营
- 禁止爬取用户隐私数据
- 遵守robots.txt协议
- 控制请求频率(建议每秒不超过1次)
结语:爬虫工程师的自我修养
写爬虫就像猫鼠游戏(笑),既要技术过硬,又要懂法守法。建议新手从这三个方向进阶:
- 学习Scrapy框架开发
- 研究分布式爬虫架构
- 掌握反爬与反反爬的攻防策略
(最后啰嗦)记住:我们的目标是学习技术,不是搞破坏!遇到难爬的网站就放弃吧,换个目标练手不香吗?