免费编程软件「python+pycharm」
链接:https://pan.quark.cn/s/48a86be2fdc0
每天都有数百万读者在小说网站追更,但免费章节看一半突然收费、网站广告弹窗满天飞、手机浏览器卡成PPT……这些痛点让许多读者选择自己动手爬取全本小说。用Python写个爬虫,不仅能实现自动下载,还能把小说转换成mobi/epub格式,在Kindle或微信读书上舒服阅读。
# 安装必要库
pip install requests beautifulsoup4 fake_useragent
以笔趣阁为例(示例域名,实际使用时请替换):
import requests
from bs4 import BeautifulSoup
def get_chapter(url):
headers = {'User-Agent': 'Mozilla/5.0'}
try:
response = requests.get(url, headers=headers, timeout=10)
soup = BeautifulSoup(response.text, 'html.parser')
# 笔趣阁内容通常在id="content"的div中
content = soup.find('div', id='content').text.strip()
return content
except Exception as e:
print(f"获取章节失败: {e}")
return None
# 测试获取第一章
print(get_chapter("https://www.example.com/book/1.html"))
def get_chapter_list(book_url):
headers = {'User-Agent': 'Mozilla/5.0'}
response = requests.get(book_url, headers=headers)
soup = BeautifulSoup(response.text, 'html.parser')
# 笔趣阁目录通常在class="listmain"的ul中
chapters = []
for li in soup.select('.listmain ul li a'):
chapters.append({
'title': li.text.strip(),
'url': li['href']
})
return chapters
# 获取某本书所有章节链接
chapters = get_chapter_list("https://www.example.com/book/")
for i, chap in enumerate(chapters[:5], 1): # 打印前5章
print(f"{i}. {chap['title']}: {chap['url']}")
import concurrent.futures
def download_book(chapters, output_file):
all_content = []
def fetch_chapter(chapter):
content = get_chapter(chapter['url'])
if content:
return f"\n\n{chapter['title']}\n\n{content}"
return ""
with concurrent.futures.ThreadPoolExecutor(max_workers=5) as executor:
results = executor.map(fetch_chapter, chapters)
all_content = [content for content in results if content]
with open(output_file, 'w', encoding='utf-8') as f:
f.write("\n".join(all_content))
print(f"小说已保存至 {output_file}")
# 使用示例
chapters = get_chapter_list("https://www.example.com/book/")
download_book(chapters, "小说全本.txt")
使用ebooklib
库生成epub:
from ebooklib import epub
def create_epub(chapters, book_name):
book = epub.EpubBook()
book.set_title(book_name)
book.set_language('zh')
# 添加章节
for chapter in chapters:
content = get_chapter(chapter['url'])
if content:
c1 = epub.EpubHtml(
title=chapter['title'],
file_name=f"{chapter['title'].replace('/', '_')}.xhtml",
lang='zh',
content=f"<h1>{chapter['title']}</h1><p>{content}</p>"
)
book.add_item(c1)
book.toc.append((chapter['title'], [c1], False))
# 添加元数据
book.add_author('匿名')
# 生成epub
epub.write_epub(f"{book_name}.epub", book, {})
print(f"EPUB文件已生成: {book_name}.epub")
# 使用示例
chapters = get_chapter_list("https://www.example.com/book/")
create_epub(chapters, "我的小说")
# 随机User-Agent
from fake_useragent import UserAgent
def get_random_ua():
ua = UserAgent()
return ua.random
headers = {'User-Agent': get_random_ua()}
import random
class ProxyPool:
def __init__(self):
# 购买站大爷代理IP
self.proxies = [
{'http': 'http://1.1.1.1:8080'},
{'http': 'http://2.2.2.2:8080'},
# 更多代理...
]
def get_proxy(self):
return random.choice(self.proxies)
# 使用代理
proxy = ProxyPool().get_proxy()
response = requests.get(url, headers=headers, proxies=proxy, timeout=10)
对于简单的图形验证码,可以使用pytesseract
:
from PIL import Image
import pytesseract
import io
def solve_captcha(img_bytes):
img = Image.open(io.BytesIO(img_bytes))
# 转换为灰度图提高识别率
img = img.convert('L')
# 二值化处理
threshold = 140
table = []
for i in range(256):
if i < threshold:
table.append(0)
else:
table.append(1)
img = img.point(table, '1')
return pytesseract.image_to_string(img)
# 使用示例(需要先获取验证码图片)
# captcha_text = solve_captcha(captcha_img_bytes)
使用selenium
模拟真实用户操作:
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
def selenium_get(url):
chrome_options = Options()
chrome_options.add_argument("--headless") # 无头模式
chrome_options.add_argument(f"user-agent={get_random_ua()}")
driver = webdriver.Chrome(options=chrome_options)
driver.get(url)
# 等待页面加载(可根据实际情况调整)
driver.implicitly_wait(10)
# 获取内容(示例获取body文本)
content = driver.find_element_by_tag_name('body').text
driver.quit()
return content
novel_crawler/ | |
---|---|
├── config.py # 配置文件 | |
├── proxies.py # 代理池管理 | |
├── parser.py # 页面解析器 | |
├── downloader.py # 下载器 | |
├── converter.py # 格式转换 | |
└── main.py # 主程序 |
# main.py
from parser import NovelParser
from downloader import Downloader
from converter import EpubConverter
def main():
book_url = input("请输入小说目录页URL: ")
parser = NovelParser()
chapters = parser.get_chapters(book_url)
downloader = Downloader()
downloader.download_all(chapters, "小说.txt")
converter = EpubConverter()
converter.to_epub(chapters, "我的小说")
if __name__ == "__main__":
main()
Q1:被网站封IP怎么办? A:立即启用备用代理池,建议使用住宅代理(如站大爷IP代理),配合每请求更换IP策略。可以设置重试机制,当连续3次请求失败时自动切换代理。
Q2:遇到403 Forbidden错误如何解决?
A:首先检查User-Agent是否有效,尝试添加更多请求头如Referer
、Cookie
。如果问题依旧,可能是IP被封,需要更换代理。
Q3:如何处理动态加载的内容? A:对于JavaScript渲染的页面,使用selenium或playwright模拟浏览器行为。也可以分析XHR请求,直接抓取API接口数据。
Q4:下载的小说内容混乱怎么办? A:检查CSS选择器是否准确,不同网站结构可能不同。建议在解析前打印HTML片段确认选择器正确性。可以添加异常处理,跳过解析失败的章节。
Q5:如何提高下载速度? A:使用多线程/异步请求(推荐aiohttp),合理设置并发数(通常5-10个线程)。对于大文件,可以分块下载后合并。
Q6:爬取的小说有乱码怎么办?
A:确保响应编码正确,可以尝试response.encoding = response.apparent_encoding
。保存文件时指定编码utf-8
或gbk
(根据网站实际编码)。
Q7:如何避免法律风险? A:仅爬取允许公开获取的内容,遵守网站的robots.txt协议。不要将爬取的内容用于商业用途,建议仅供个人学习研究使用。
time.sleep()
,避免给服务器造成过大压力通过这个项目,你不仅学会了Python爬虫技术,更掌握了应对反爬的策略。记住技术本身没有对错,关键在于如何使用。希望这些代码能帮助你享受纯净的阅读体验!
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。