前言:
我写过很多爬取有声小说的案例,有些是因为审核的原因,不能放出来,在加上平时就喜欢听有声小说,但是现在的有声小说大部分都收费了,作为一个玩爬虫的,收费听小说是自己不能忍的,最近发现了一部小说通过分析,是不需要付费可以爬取下来的,特把这次的爬取过程给大家总结出来,希望对大家有一定的帮助。
网页分析:
既然提取有声书,那必然要找到该音频的接口了,我们打开开发者工具,我们可以先尝试点击一下播放,小说就开始播放了,然后暂停播放,我们定位到media标签下,可以看到一个后缀是MP3的链接数据,
我们继续分析,
如图所示,可以看出该MP3的数据其实就是一个网址,这个就是我们需要最后找到的数据地址,现在我们需要找到这个地址是如何生成的,我们可以通过搜索来查找这个MP3的信息;
通过搜索可以看出有一个index开头的数据包,我们打开它的preview选项,经过分析,可以清晰的看出play_url下就是真正的mp3链接地址,这个就是我们需要的的接口地址,下面就要看看这个接口地址是如何生成的,我们切换到payload标签下,可以看到里面有很多参数数据:
通过多次尝试,大部分的参数都是固定的,只有encode_album_audio_id这个参数是变化的,每一个参数就代表了一个新的有声书链接数据,下面就要找到这些id的数据是在哪里的,其实在该有声书的主页里面就有每集小说对应的id数据,
我们需要把这个id数据提取出来,另外提取出来每集的标题名字,通过这个id重新构建这个api接口链接,然后再发送请求,提取出来真正的MP3链接数据,最后保存这些数据就可以了。
代码部分:
本案例所用到的模块:
import httpx
import parsel
import json
import wget
import os
创建url列表:
def get_url_list():
"""创建url列表的方法,本案例我之爬取一页数据,要爬取多页数据,可以把2这个数字改成自己想爬取的页数
Returns:
_type_: _description_
"""
return [page_url.format(i) for i in range(1, 2)]
发送请求,获取响应数据:
def parse_url(url):
"""发送请求,获取响应数据的方法
Args:
url (_type_): _description_
Returns:
_type_: _description_
"""
r = httpx.get(url, headers=headers)
return r.content.decode()
提取有声书的标题和id:
def get_link_title(html_str):
"""提取有声书的标题和id的方法
Args:
html_str (_type_): _description_
Yields:
_type_: _description_
"""
for item in parsel.Selector(html_str).css('.tsa_d3_d2_ul>li'):
yield {
'audio_book_title': item.css('div>span>a::text').get(),
'audio_book_id': item.css('li::attr(data-encode_album_audio_id)').get()
}
提取真正的有声书MP3地址:
def get_audio_book_url(json_str):
"""提取真正的有声书MP3地址的方法
Args:
json_str (_type_): _description_
Returns:
_type_: _description_
"""
json_data = json.loads(json_str)
audio_book_url = json_data['data']['play_url']
return audio_book_url
保存有声书:
def save_audio(audio_book_url, data):
"""保存有声书的方法
Args:
audio_book_url (_type_): _description_
data (_type_): _description_
"""
path = os.path.join('猎宝天官', f"{data['audio_book_title']}.mp3")
file_name = wget.download(audio_book_url, out=path)
print(file_name)
实现程序主要逻辑思路:
def main():
"""实现程序的主要逻辑思路
"""
# 1.创建url列表
url_list = get_url_list()
for url in url_list:
# 2.发送请求,获取响应数据
html_str = parse_url(url)
# 3.提取有声书的标题和id的方法
datas = get_link_title(html_str)
for data in datas:
# 4.再次发送请求,获取响应数据
json_str = parse_url(api_url.format(data['audio_book_id']))
# 5.提取真正的有声书MP3
audio_book_url = get_audio_book_url(json_str)
# 6.保存有声书
save_audio(audio_book_url,data)