需要安装的第三方库:
- requests
- BeautifulSoup4
- lxml(非必须,但推荐使用)
打开终端输入:
pip install requests beautifulsoup4
本文的目的是爬取久久小说网全站的小说,首先打开首页看一看。

浏览一下就能发现,可以通过上面的分类访问到所有小说。现在就进入一个分类具体分析。

打开浏览器的开发者工具,可以看到每一条小说的信息都分别包含在<div class="listbg"></div>
当中。其中的<a>
标签就有我们想要的所有信息:
- 属性
href="/txt/71515.html"
就是小说详情页的链接,后续只需拼接成"https://www.txt909.com/txt/71515.html"
即可 - 属性
title="斗罗之躺平麒麟,比比东偷听心声"
就是小说的名字,后续保存时用来命名
虽然已经能够获取每条小说详情页信息了,但是还需要获取到下载链接才行,所以继续进入小说的详情页。

进去后发现了”进入下载列表“的按钮,继续点开。

进入下载界面后,有一个”下载TXT“的按钮,点进去发现就能下载小说了(这网站真良心,没有跳各种广告,也没有关注什么公众号就能下载),链接为http://www.vbiquge.co/api/txt_down.php?articleid=71515&articlename=斗罗之躺平麒麟,比比东偷听心声
分析一下链接
- 基础链接为:
http://www.vbiquge.co/api/txt_down.php
- 参数有:
articleid=71515
articlename=斗罗之躺平麒麟,比比东偷听心声
第一个参数是文章ID,有没有发现这个ID似曾相识,不难发现,这就是文章详情页链接/txt/71515.html
中的数字。第二个参数是文章的名字。正常说来,应该通过ID就能下载到小说,我们试着把articlename
参数去掉,直接访问http://www.vbiquge.co/api/txt_down.php?articleid=71515
。不出所料,小说同样被下载下来了,只是文件名为空,articlename
参数的作用只是提供保存的文件名。
至此,工作已经完成一半了,从头开始分析一下。
- 我们先从某一个分类页面下手,通过
<div class="listbg"></div>
标签中的<a>
标签来获取小说详情页链接与小说名。 - 因为最后下载小说仅需要提供ID,即小说详情页链接中的数字,所以中间访问详情页、访问下载页的操作都可以略去。
- 最后用第一步获取的小说名给文件命名。
现在开始写代码:
首先导入requests
库用于网页请求以及获取响应,导入BeautifulSoup
模块用于解析网页源码。
import requests
from bs4 import BeautifulSoup
整个程序可以用获取id和名字、下载小说两部分组成,结构如下:
# 定义一个函数,需要分类页面的链接作为参数传入
def get_details(url):
'''返回小说的名字和id'''
pass
# 定义一个函数来下载小说,参数为下载链接和小说的名字
def download(id, title):
'''下载小说,并以小说名保存文件'''
pass
def main():
'''主程序'''
pass
if __name__ == '__main__':
main()
下面来完善返回小说名字和id的函数:
def get_details(url):
'''返回小说的名字和下载链接'''
# 访问分类页面,获得响应
resp = requests.get(url, headers=headers)
# 从响应中获取源码,采用utf-8编码
html = resp.content.decode('utf-8')
# 创建BeautifulSoup对象,解析器设置为lxml,如果没有也可以使用Python自带的html-parser
soup = BeautifulSoup(html, 'lxml')
# 获取到所有<div class="listbg"></div>标签,返回一个列表
divs = soup.find_all('div', class_='listbg')
# 创建一个字典,key为小说名,value为ID
novel_dic = {}
# 这里采用for循环来写,如果熟悉字典生成式可以一行代码搞定
for div in divs:
# 此处的div也是一个BeautifulSoup对象
# 获取到<a>标签,返回一个BeautifulSoup对象
a = div.find('a')
# 获取<a>标签的title属性
title = a.attrs['title']
# 获取<a>标签的href属性
href = a.attrs['href']
# 在href中截取数字部分
article_id = href[5:-5]
# 组成字典
novel_dic[title] = article_id
return novel_dic
如果不太明白可以将代码复制到本地,自行传入一个分类页面链接进行调用,或者进行单步调试查看结果
print(get_details('https://www.txt909.com/html/chuanyue/'))
将会得到类似于以下的结果
{'锦绣农家之福嫁天下': '77360', '宁城李子怡': '66923', '退婚后!玄学大佬靠算命轰动世界': '78502', '我妈才是穿越主角': '78196', '疯批暴君被福运农女喊去种田': '78142', '柯南之
魔童降世': '76904', '八零替嫁辣妻有空间': '78180', '穿越五零:末世夫妻咸鱼躺赢!': '73020', '重生农家:她带着拖油瓶逆袭': '78410', '九爷的心肝又杀出重围了': '78455', '我,签
到百年,被美女师尊曝光了': '76921', '惊!疯批狐王哭着求我摸尾巴': '78501', '穿越古代去
逃荒随身带着时空门': '78509', '修仙女配改拿龙傲天剧本': '77620', '钢铁苏联': '7383', '
海贼从岛主到国王': '76639', '道主有点咸': '76320', '寒门祸害': '1970', '踹了明爷后,他
每晚哭着求我抱!': '77176', '穿越后,我被竹马拖累成了皇后': '70294', '重生年代:炮灰长
姐带妹逆袭': '77565', '为什么正常夺舍的只有我': '76104', '斗罗之躺平麒麟,比比东偷听心
声': '71515', '修仙女配要上天': '76120', '每天都在醋自己[快穿]': '77066', '最强终极兵王宁城李子怡': '66922', '半妖农女有空间': '78323'}
接着完成download
函数
def download(id, title):
'''下载小说,并以小说名保存文件'''
# 有的名字中带有问号,保存文件时会出错,直接替换掉
title = title.replace('?', '')
# 合成下载链接
url = f'http://www.vbiquge.co/api/txt_down.php?articleid={id}'
resp = requests.get(url, headers=headers)
# 将文件储存为"分类/小说名.txt"
with open(f'{category}/{title}.txt', 'a', encoding='utf-8') as f:
f.write(resp.text)
print(f'{title}下载成功')
此时,只需再修改主程序的代码,就能完成第一页的小说下载了。
还需导入os模块来判断目录是否存在
import os
def main():
'''主程序'''
# 判断分类目录是否存在,若不存在则创建
if not os.path.exists('./'+category):
os.mkdir('./'+category)
# 接受函数返回的数据
novel_dic = get_details(categories[category])
# 遍历字典,对每一条数据调用download函数
for title, novel_id in novel_dic.items():
download(novel_id, title)
完整代码如下:
# 定义一个函数,需要分类页面的链接作为参数传入
import requests
from bs4 import BeautifulSoup
import os
def get_details(url):
'''返回小说的名字和下载链接'''
# 访问分类页面,获得响应
resp = requests.get(url, headers=headers)
# 从响应中获取源码,采用utf-8编码
html = resp.content.decode('utf-8')
# 创建BeautifulSoup对象,解析器设置为lxml,如果没有也可以使用Python自带的html-parser
soup = BeautifulSoup(html, 'lxml')
# 获取到所有<div class="listbg"></div>标签,返回一个列表
divs = soup.find_all('div', class_='listbg')
# 创建一个字典,key为小说名,value为ID
novel_dic = {}
# 这里采用for循环来写,如果熟悉字典生成式可以一行代码搞定
for div in divs:
# 此处的div也是一个BeautifulSoup对象
# 获取到<a>标签,返回一个BeautifulSoup对象
a = div.find('a')
# 获取<a>标签的title属性
title = a.attrs['title']
# 获取<a>标签的href属性
href = a.attrs['href']
# 在href中截取数字部分
article_id = href[5:-5]
# 组成字典
novel_dic[title] = article_id
return novel_dic
# 定义一个函数来下载小说,参数为下载链接和小说的名字
def download(id, title):
'''下载小说,并以小说名保存文件'''
# 有的名字中带有问号,保存文件时会出错,直接替换掉
title = title.replace('?', '')
# 合成下载链接
url = f'http://www.vbiquge.co/api/txt_down.php?articleid={id}'
resp = requests.get(url, headers=headers)
# 将文件储存为"分类/小说名.txt"
with open(f'{category}/{title}.txt', 'a', encoding='utf-8') as f:
f.write(resp.text)
print(f'{title}下载成功')
def main():
'''主程序'''
# 判断分类目录是否存在,若不存在则创建
if not os.path.exists('./'+category):
os.mkdir('./'+category)
# 接受函数返回的数据
novel_dic = get_details(categories[category])
# 遍历字典,对每一条数据调用download函数
for title, novel_id in novel_dic.items():
download(novel_id, title)
print('下载完成')
# 定义几个全局变量,方便使用
# 设置user agent,以免有反爬机制
headers = {
'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/101.0.4951.54 Safari/537.36'
}
# 所有分类以及分类所对应的页面链接
categories = {
'穿越小说': 'https://www.txt909.com/html/chuanyue/',
'言情小说': 'https://www.txt909.com/html/yanqing/',
'现代都市': 'https://www.txt909.com/html/dushi/',
'耽美百合': 'https://www.txt909.com/html/baihe/',
'历史架空': 'https://www.txt909.com/html/lishi/',
'美文同人': 'https://www.txt909.com/html/tongren/',
'武侠仙侠': 'https://www.txt909.com/html/wuxia/',
'玄幻小说': 'https://www.txt909.com/html/xuanhuan/',
'惊悚悬疑': 'https://www.txt909.com/html/jingsong/',
'科幻小说': 'https://www.txt909.com/html/kehuan/',
'网游竞技': 'https://www.txt909.com/html/wangyou/'}
# 要爬取的分类
category = '言情小说' # 指定下载分类
if __name__ == '__main__':
main()
输出如下:
自律的我简直无敌了下载成功
霸天龙帝下载成功
入赘王婿下载成功
超级修真弃少下载成功
至尊保安下载成功
空间之归园田居下载成功
柯南之敬酒不吃吃罚酒下载成功
·
·
·
下载完成
到此为止,第一部分教程结束,有不明白的地方可在评论区提出,建议自行复制代码到本地运行。
第二部分教程将讲解如何爬取所有页面,实现流式传输,多进程下载以及细节优化。
Comments NOTHING