Python爬取久久小说网全站小说(一)

Kiaana Lv2

[warning]本教程仅限研究学习,不得用于任何违法以及损害他人权利的行为,所做出的任何行为与作者无关[/warning]

需要安装的第三方库:

  • requests
  • BeautifulSoup4
  • lxml(非必须,但推荐使用)

打开终端输入:

1
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参数的作用只是提供保存的文件名。

至此,工作已经完成一半了,从头开始分析一下。

  1. 我们先从某一个分类页面下手,通过<div class="listbg"></div>标签中的<a>标签来获取小说详情页链接小说名
  2. 因为最后下载小说仅需要提供ID,即小说详情页链接中的数字,所以中间访问详情页、访问下载页的操作都可以略去。
  3. 最后用第一步获取的小说名给文件命名。

现在开始写代码:

首先导入requests库用于网页请求以及获取响应,导入BeautifulSoup模块用于解析网页源码。

1
2
import requests
from bs4 import BeautifulSoup

整个程序可以用获取id和名字下载小说两部分组成,结构如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# 定义一个函数,需要分类页面的链接作为参数传入
def get_details(url):
'''返回小说的名字和id'''
pass

# 定义一个函数来下载小说,参数为下载链接和小说的名字
def download(id, title):
'''下载小说,并以小说名保存文件'''
pass

def main():
'''主程序'''
pass

if __name__ == '__main__':
main()

下面来完善返回小说名字和id的函数:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
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

如果不太明白可以将代码复制到本地,自行传入一个分类页面链接进行调用,或者进行单步调试查看结果

1
print(get_details('https://www.txt909.com/html/chuanyue/'))

将会得到类似于以下的结果

1
2
3
4
5
6
7
8
{'锦绣农家之福嫁天下': '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函数

1
2
3
4
5
6
7
8
9
10
11
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模块来判断目录是否存在

1
2
3
4
5
6
7
8
9
10
11
12
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)

完整代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
# 定义一个函数,需要分类页面的链接作为参数传入
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()

输出如下:

1
2
3
4
5
6
7
8
9
10
11
自律的我简直无敌了下载成功
霸天龙帝下载成功
入赘王婿下载成功
超级修真弃少下载成功
至尊保安下载成功
空间之归园田居下载成功
柯南之敬酒不吃吃罚酒下载成功
·
·
·
下载完成

到此为止,第一部分教程结束,有不明白的地方可在评论区提出,建议自行复制代码到本地运行。

第二部分教程将讲解如何爬取所有页面,实现流式传输,多进程下载以及细节优化。

  • 标题: Python爬取久久小说网全站小说(一)
  • 作者: Kiaana
  • 创建于 : 2022-05-14 14:48:31
  • 更新于 : 2023-09-21 17:52:52
  • 链接: https://www.kiaana.cn/posts/python-web-scraping-jiuku-xiaoshuo-part-1/
  • 版权声明: 本文章采用 CC BY-NC-SA 4.0 进行许可。
 评论
此页目录
Python爬取久久小说网全站小说(一)