爬取听书网有声小说音频数据

前言:

朋友最近迷上了听有声小说,可是因为很多的有声小说网站都需要vip才能听,所以他想让我帮他把小说弄下来,方便他可以随时在手机上听。我在网上搜了一下他听的这部小说,的确有很多大的听书网站都需要vip才能听,所以我就找了一个小的网站,帮他把小说爬取了下来。因为他听的小说是一个很有名的作者的,为了保护作者的权益,本文的案例就没有拿这个作者的小说来进行爬取,用了另一部小说来进行爬取讲解,大概的爬取思路都是一样,所以可以借鉴本文的思路。

本案例网址:https://www.88tingshu.com/29101/

一、分析网页

本案例的这部小说一共有178个章节,所以也就对应了178个音频数据,我们需要爬取到小说的名字,每一个章节的链接地址,然后在分析每一个链接地址,找到真实的音频数据地址。如图:
在这里插入图片描述

网页的链接通过查看开发者工具,可以分析出网页是个html的数据网页,数据也就在html网页源码中,继续分析,随便点开一个章节链接,网页跳转到了另一个窗口,然后会自动播放该章节的小说,如图:
在这里插入图片描述

其实要找到该音频文件很简单,只要定位到network下的media选项就可以看到正在播放的音频数据了,如图:
在这里插入图片描述

在这里插入图片描述

从图中可以看出,该音频数据是一个m4a格式的音频数据,这个网址就是真实的音频地址,那么问题来了,只有这一个网址,也只能爬取一个章节的小说,我们的目的是爬取所有章节的小说,所以显然只知道这个小说的音频地址是没用的,下面我们就需要把这个音频地址的出处找出来,通过经验,我们可以搜索这个音频地址的后面的文件名字,
在这里插入图片描述
通过搜索该名字我们定位到了一个新的网页链接,如图:

在这里插入图片描述

可以很明显看出,和真实的音频地址是一样的,只不过缺少了**.m4a**这几个字,我们大概断定这个网页就是包含了真实音频数据的地址网页,可是这是一个新的网页地址,那么这个地址又是那里来的呢,没关系,我们继续搜索该地址试试,
在这里插入图片描述

可以看出我们通过搜索又定位到了一个新的网页,里面有一个iframe的标签,该标签下有一个src的属性,里面的网址和我们之前搜索的网页网址大概是一样的,只不过这个网址不全,只有网址的后半段,缺少前半段,我们只需要补全前半段就可以了,通过这一系列的分析,大概确定了,该网址就是包含了上面网址的数据网址,最后只要确定该网址是哪一个网址就行了,经过确定,该网址就是每一个章节链接的地址,这整个分析过程就算完成了,基本就可以把这个小说的有声书给爬取下来了。

现在大概说一下爬取思路,先通过小说首页把每一个章节的链接地址和小说名字给爬取下来,然后在通过爬取下来的每一个章节的链接,找到该链接地址里面的包含的另一个包含真实音频数据的小说链接,在通过这个链接找到真实的音频数据,最后保存数据。

本案例所用到的模块:
import requests
import parsel
import re
import os
from urllib.request import urlretrieve
from tqdm import tqdm

二、发送请求,获取响应数据

    def parse_url(self, url, headers):
        """
        发送请求,获取响应数据的方法
        :param url:
        :param headers:
        :return:
        """
        response = requests.get(url, headers=headers)
        if response.status_code == 200:
            return response.text
        else:
            print('请求失败')

三、提取小说每个章节的链接地址

  def get_chapter_url(self, html_str):
        """
        提取小说章节的url的方法
        :param html_str:
        :return:
        """
        html = parsel.Selector(html_str)
        # 提取小说章节地址列表
        chapter_urls = html.css('#playlist>ul>li>a::attr(href)').extract()
        chapter_urls = [self.SHU_TEMP_URL.format(i) for i in chapter_urls]
        # 提取小说名字
        audio_shu_name = html.css('.book-title::text').extract_first().strip()
        return chapter_urls, audio_shu_name

四、提取含有小说真实音频地址的链接地址

    def get_audio_temp_url(self, html_str2):
        """
        提取含有小说真实地址的url的方法
        :param html_str2:
        :return:
        """
        html = parsel.Selector(html_str2)
        audio_temp_url = html.css('iframe::attr(src)').extract_first()
        audio_temp_url = self.SHU_TEMP_URL.format(audio_temp_url)
        return audio_temp_url

五、提取该地址下的真实音频数据地址

    def get_audio_url(self, html_str3):
        """
        提取小说真实的url地址的方法
        :param html_str3:
        :return:
        """
        audio_url = re.findall("mp3:'(.*?)'", html_str3, re.S)[0]
        if 'm4a' in audio_url:
            return audio_url
        else:
            return audio_url + '.m4a'

六、保存音频数据

    def down_audio(self, audio_url, audio_shu_name, num):
        """
        下载有声小说的方法
        :param audio_url:
        :param audio_shu_name:
        :param num:
        :return:
        """
        path = f'{audio_shu_name}'
        isExists = os.path.exists(path)
        file_path = os.path.join(path, f'{audio_shu_name}_{num}.mp3')
        if not isExists:
            os.makedirs(path, exist_ok=True)
            urlretrieve(audio_url, file_path)
            print(f"{audio_shu_name}_{num}---下载完成")
        else:
            urlretrieve(audio_url, file_path)
            print(f"{audio_shu_name}_{num}---下载完成")

七、具体实现逻辑思路的代码

 def run(self):
        """
        实现主要逻辑思路
        :return:
        """
        # 1.发送请求,获取响应数据
        html_str = self.parse_url(self.SHU_URL, self.headers)
        # 2.提取小说章节的url
        chapter_urls, audio_shu_name = self.get_chapter_url(html_str)
        tqdm_chapter_urls = tqdm(chapter_urls)
        for num, chapter_url in enumerate(tqdm_chapter_urls):
            # 3.对小说章节url发送请求,获取响应数据
            html_str2 = self.parse_url(chapter_url, self.headers)
            # 4.提取含有小说真实地址的url
            audio_temp_url = self.get_audio_temp_url(html_str2)
            # 5.对这个url地址发送请求,获取响应数据
            html_str3 = self.parse_url(audio_temp_url, self.headers)
            # 6.提取真实的url地址
            audio_url = self.get_audio_url(html_str3)
            # 7.下载小说
            self.down_audio(audio_url, audio_shu_name, num + 1)
完成效果展示:

在这里插入图片描述
在这里插入图片描述

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值