首页 编程教程正文

爬虫入门:爬取某山m4a格式音频

piaodoo 编程教程 2020-02-22 22:16:24 1239 0 python教程

本文来源吾爱破解论坛

准备用爬虫入门python,做个练习。
首先解析一下网页,随便找个音频打开,我比较喜欢鬼谷子,就选他老人家了。
我用的360浏览器,直接F12,找到音频列表那片区域。
一直点到音频的的区域

1.png (16.2 KB, 下载次数: 0)

下载附件  保存到相册

2020-2-19 20:36 上传


获得第一个有用的信息:
div的class是"text _Vc",网页都是批量生成的,所以别的网页肯定也一样。
不行的话,随便找几个验证一下。确认没问题。
然后点开第一个网页,打开音频的播放页面。
点小三角播放,继续看F12,出现一个好大的audio,高度疑似目标。

2.png (68.12 KB, 下载次数: 0)

下载附件  保存到相册

2020-2-19 20:36 上传


点开后有个请求的连接,复制下来,输入到浏览器看一下。

3.png (40.12 KB, 下载次数: 0)

下载附件  保存到相册

2020-2-19 20:36 上传


看src,后面有个地址,是m4a格式的,再复制下来到浏览器看看。
没错,响了。

4.png (36.22 KB, 下载次数: 0)

下载附件  保存到相册

2020-2-19 20:56 上传


而且,这个数字和音频播放网页地址的id是一个。
确认过眼神,是要爬的虫。
这样图二的地址需要记一下,图三的是最终的资源地址
因为是点了以后才会出现图二的地址,应该是所谓的动态加载(还没学到,了解点“动态”这个词,猜的)
那这样,三个地址都有了。
第一个地址手动输入(类似于这样的/youshengshu/29497459/),然后用BeautifulSoup把class="text _Vc"的tag匹配出来。
最后提取出音频播放页面的地址(图1的herf)和音频名称。
顺便页面总数也匹配出来保存一下。
接下来把提取到的地址最后那组数字也提取出来,拼接一个图2的地址。
再用这个地址获取图三的数据,就是src后面那一串以https开头,m4a结尾的字符串。
拿到以后就有了音频资源的地址,下载下了就完成了。
下面上源码,编译环境是3.7,需要bs4和fake_useragent这俩第三方包。

'''
python爬虫练习
获取一个专辑的网页,解析出每个音频的资源地址,下载到本地
'''
import os
import re
from urllib import request
from bs4 import BeautifulSoup
from fake_useragent import UserAgent

def get_html(target_url):
    '''
    将网页解析为utf-8格式的BeautifulSoup
    :param target_url: 网页地址
    :return: 返回一个BeautifulSoup对象
    '''
    opener = request.build_opener()
    opener.addheaders = [('User-Agent', UserAgent().random)]
    request.install_opener(opener)
    page = request.urlopen(target_url).read()
    return BeautifulSoup(page, 'lxml')

def get_page(url_page, pagenumber):
    '''
    取得专辑某一页面的资源
    :param url_page: 专辑网页地址
    :param pagenumber: 专辑的页面序号
    :return: 返回一个列表[页码-本页面编号, 音频名称, 音频网页地址]
    '''
    target_page = get_html(url_page)
    package_li = str(target_page.find_all(attrs={'class', 'text _Vc'}))
    pattern = '<a href="(.+?)".+?title="(.+?)">'
    targets = re.findall(pattern, package_li)
    page_source = []
    index = 1
    for target in targets:
        target_link = target[0]
        target_title = target[1]
        page_source.append([str(pagenumber)+"."+str(index), target_title, target_link])
        print("获取第%d条记录" % index)
        index += 1

    return page_source

def get_all_pages(page_num, base_url):
    '''
    获取所有页面的资源列表
    :param page_num: 专辑的页面数量
    :param base_url: 专辑页面的地址
    :return: 返回一个专辑所有页面的资源列表[页码-本页面编号, 音频名称, 音频网页地址]
    '''
    source_list = []
    index = 1
    for i in range(int(page_num)):
        if i == 0:
            print("第%d页" % index)
            # print(base_url)
            source_list.append(get_page(base_url, index))
            index += 1
            continue
        print("第%d页" % index)
        # print(base_url + "p" + str(i + 1) + "/")
        source_list.append(get_page((base_url + "p" + str(i + 1) + "/"), index))
        index += 1

    return source_list

def get_source(target_url):
    '''
    获取专辑全部音频资源
    :param target_url: 专辑的首页面地址
    :return: 返回一个资源列表[页码-本页面编号, 音频名称, 音频网页地址], 一个专辑名称
    '''
    target_html = get_html(target_url)
    # <input type="number" placeholder="请输入页码" step="1" min="1" max="9" class="control-input _Xo" value="">
    pattern = r'max="(\d)"'
    page_max = (re.findall(pattern, str(target_html)))[0]
    # <h1 class="title lO_">鬼谷子智慧</h1>
    pattern = r'<h1 class="title lO_">(.+?)</h1>'
    folder = (re.findall(pattern, str(target_html)))[0]
    tmp_source_list = get_all_pages(page_max, target_url)
    source_list = []
    for item in tmp_source_list:
        source_list.extend(item)
    return source_list, folder

def analysis_data(source):
    '''
    解析资源页面,从返回的数据中提取m4a音频的地址
    :param source: 音频资源列表
    :return: 返回一个列表,其中每个元素都是一个m4a音频的地址
    '''
    pattern = r'.+/(\d+)'
    url_list = []
    index = 1
    for item in source:
        res = 'https://www.ximalaya.com/revision/play/v1/audio?id=' \
              + (re.findall(pattern, item[2]))[0] + '&ptype=1'
        url_list.append(res)
        print("解析链接  %d/%d" % (index, len(source)))
        # debug
        print(res)
        index += 1
    # https://www.ximalaya.com/revision/play/v1/audio?id=67064624&ptype=1
    response_list = [str(get_html(a_url)) for a_url in url_list]
    # debug 如果上面url打开后资源不是m4a需要修改正则表达式
    pattern = '"src":"(.+?)","'
    print("没有死,稍等")
    return [(re.findall(pattern, response))[0] for response in response_list]

def mkdir(file_path):
    '''
    创建用于保存的文件夹
    :param file_path: 文件夹路径
    '''
    folder = os.path.exists(file_path)
    if not folder:
        os.mkdir(file_path)
        print("创建文件夹")
    else:
        print("文件夹已存在")

def crawl_source(file_url, file_path):
    '''
    爬取音频资源
    :param file_url: 音频资源的地址 
    :param file_path: 本地文件名
    '''
    try:
        opener = request.build_opener()
        opener.addheaders = [('User-Agent', UserAgent().random)]
        request.install_opener(opener)
        request.urlretrieve(file_url, file_path)
    except Exception as e:
        print(e)

def download_source(file_url, file_path, source):
    '''
    批量下载音频资源
    :param file_url: 全部音频资源地址的列表 
    :param file_path: 本地文件夹路径
    :param source: 音频资源的列表,用于创建文件名,[页码-编号, 音频名称, 音频网页地址]
    '''
    name_list = [str(item[0]) + "." + item[1] for item in source]
    index = 1
    # 查看url防止出错
    for item in file_url:
        print(item)
    for i in range(len(file_url)):
        file_name = file_path + name_list[i] + '.m4a'
        crawl_source(file_url[i], file_name)
        print("当前进度:%d/%d" % (index, len(file_url)))
        index += 1
    print("下载完成,当前目录:%s" % file_path)

if __name__ == "__main__":
    # 网页专辑地址
    url = 'https://www.ximalaya.com/youshengshu/29497459/'
    # 获取专辑内每个音频的播放页面地址,专辑名
    source, folder_name = get_source(url)
    # 解析每个音频播放网页,获得一个列表,包含专辑的全部音频链接
    # [id, 音频名称, 音频资源地址]
    download_list = analysis_data(source)
    # 合成本地保存路径,并生产文件夹
    folder_path = "./source/" + folder_name + "/"
    mkdir(folder_path)
    print("准备完毕,开始下载")
    # 下载资源到本地
    download_source(download_list, folder_path, source)

版权声明:

本站所有资源均为站长或网友整理自互联网或站长购买自互联网,站长无法分辨资源版权出自何处,所以不承担任何版权以及其他问题带来的法律责任,如有侵权或者其他问题请联系站长删除!站长QQ754403226 谢谢。

有关影视版权:本站只供百度云网盘资源,版权均属于影片公司所有,请在下载后24小时删除,切勿用于商业用途。本站所有资源信息均从互联网搜索而来,本站不对显示的内容承担责任,如您认为本站页面信息侵犯了您的权益,请附上版权证明邮件告知【754403226@qq.com】,在收到邮件后72小时内删除。本文链接:http://www.piaodoo.com/8059.html

评论

搜索