[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
参数的作用只是提供保存的文件名。
至此,工作已经完成一半了,从头开始分析一下。
- 我们先从某一个分类页面下手,通过
<div class="listbg"></div>
标签中的<a>
标签来获取小说详情页链接与小说名。 - 因为最后下载小说仅需要提供ID,即小说详情页链接中的数字,所以中间访问详情页、访问下载页的操作都可以略去。
- 最后用第一步获取的小说名给文件命名。
现在开始写代码:
首先导入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) html = resp.content.decode('utf-8') soup = BeautifulSoup(html, 'lxml') divs = soup.find_all('div', class_='listbg') novel_dic = {} for div in divs: a = div.find('a') title = a.attrs['title'] href = a.attrs['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) 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]) 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) html = resp.content.decode('utf-8') soup = BeautifulSoup(html, 'lxml') divs = soup.find_all('div', class_='listbg') novel_dic = {} for div in divs: a = div.find('a') title = a.attrs['title'] href = a.attrs['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) 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]) for title, novel_id in novel_dic.items(): download(novel_id, title) print('下载完成')
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
| 自律的我简直无敌了下载成功 霸天龙帝下载成功 入赘王婿下载成功 超级修真弃少下载成功 至尊保安下载成功 空间之归园田居下载成功 柯南之敬酒不吃吃罚酒下载成功 · · · 下载完成
|
到此为止,第一部分教程结束,有不明白的地方可在评论区提出,建议自行复制代码到本地运行。
第二部分教程将讲解如何爬取所有页面,实现流式传输,多进程下载以及细节优化。