zoukankan      html  css  js  c++  java
  • Python爬虫音频数据

    一:前言

    本次爬取的是喜马拉雅的热门栏目下全部电台的每个频道的信息和频道中的每个音频数据的各种信息,然后把爬取的数据保存到mongodb以备后续使用。这次数据量在70万左右。音频数据包括音频下载地址,频道信息,简介等等,非常多。
    昨天进行了人生中第一次面试,对方是一家人工智能大数据公司,我准备在这大二的暑假去实习,他们就要求有爬取过音频数据,所以我就来分析一下喜马拉雅的音频数据爬下来。目前我还在等待三面中,或者是通知最终面试消息。 (因为能得到一定肯定,不管成功与否都很开心)


    二:运行环境

    • IDE:Pycharm 2017
    • Python3.6
    • pymongo 3.4.0
    • requests 2.14.2
    • lxml 3.7.2
    • BeautifulSoup 4.5.3

    三:实例分析

    1.首先进入这次爬取的主页面http://www.ximalaya.com/dq/all/ ,可以看到每页12个频道,每个频道下面有很多的音频,有的频道中还有很多分页。抓取计划:循环84个页面,对每个页面解析后抓取每个频道的名称,图片链接,频道链接保存到mongodb。


    热门频道

    2.打开开发者模式,分析页面,很快就可以得到想要的数据的位置。下面的代码就实现了抓取全部热门频道的信息,就可以保存到mongodb中。

    start_urls = ['http://www.ximalaya.com/dq/all/{}'.format(num) for num in range(1, 85)]
    for start_url in start_urls:
        html = requests.get(start_url, headers=headers1).text
        soup = BeautifulSoup(html, 'lxml')
        for item in soup.find_all(class_="albumfaceOutter"):
            content = {
                'href': item.a['href'],
                'title': item.img['alt'],
                'img_url': item.img['src']
            }
            print(content)

    分析频道

    3.下面就是开始获取每个频道中的全部音频数据了,前面通过解析页面获取到了美国频道的链接。比如我们进入http://www.ximalaya.com/6565682/album/237771 这个链接后分析页面结构。可以看出每个音频都有特定的ID,这个ID可以在一个div中的属性中获取。使用split()和int()来转换为单独的ID。


    频道页面分析

    4.接着点击一个音频链接,进入开发者模式后刷新页面然后点击XHR,再点击一个json链接可以看到这个就包括这个音频的全部详细信息。

    html = requests.get(url, headers=headers2).text
    numlist = etree.HTML(html).xpath('//div[@class="personal_body"]/@sound_ids')[0].split(',')
    for i in numlist:
        murl = 'http://www.ximalaya.com/tracks/{}.json'.format(i)
        html = requests.get(murl, headers=headers1).text
        dic = json.loads(html)

    音频页面分析


    5.上面只是对一个频道的主页面解析全部音频信息,但是实际上频道的音频链接是有很多分页的。

    html = requests.get(url, headers=headers2).text
    ifanother = etree.HTML(html).xpath('//div[@class="pagingBar_wrapper"]/a[last()-1]/@data-page')
    if len(ifanother):
        num = ifanother[0]
        print('本频道资源存在' + num + '个页面')
        for n in range(1, int(num)):
            print('开始解析{}个中的第{}个页面'.format(num, n))
            url2 = url + '?page={}'.format(n)
            # 之后就接解析音频页函数就行,后面有完整代码说明

    分页

    6.全部代码
    完整代码地址github.com/rieuse/learnPython

    __author__ = '布咯咯_rieuse'
    
    import json
    import random
    import time
    import pymongo
    import requests
    from bs4 import BeautifulSoup
    from lxml import etree
    
    clients = pymongo.MongoClient('localhost')
    db = clients["XiMaLaYa"]
    col1 = db["album"]
    col2 = db["detaile"]
    
    UA_LIST = []  # 很多User-Agent用来随机使用可以防ban,显示不方便不贴出来了
    headers1 = {} # 访问网页的headers,这里显示不方便我就不贴出来了
    headers2 = {} # 访问网页的headers这里显示不方便我就不贴出来了
    
    def get_url():
        start_urls = ['http://www.ximalaya.com/dq/all/{}'.format(num) for num in range(1, 85)]
        for start_url in start_urls:
            html = requests.get(start_url, headers=headers1).text
            soup = BeautifulSoup(html, 'lxml')
            for item in soup.find_all(class_="albumfaceOutter"):
                content = {
                    'href': item.a['href'],
                    'title': item.img['alt'],
                    'img_url': item.img['src']
                }
                col1.insert(content)
                print('写入一个频道' + item.a['href'])
                print(content)
                another(item.a['href'])
            time.sleep(1)
    
    
    def another(url):
        html = requests.get(url, headers=headers2).text
        ifanother = etree.HTML(html).xpath('//div[@class="pagingBar_wrapper"]/a[last()-1]/@data-page')
        if len(ifanother):
            num = ifanother[0]
            print('本频道资源存在' + num + '个页面')
            for n in range(1, int(num)):
                print('开始解析{}个中的第{}个页面'.format(num, n))
                url2 = url + '?page={}'.format(n)
                get_m4a(url2)
        get_m4a(url)
    
    
    def get_m4a(url):
        time.sleep(1)
        html = requests.get(url, headers=headers2).text
        numlist = etree.HTML(html).xpath('//div[@class="personal_body"]/@sound_ids')[0].split(',')
        for i in numlist:
            murl = 'http://www.ximalaya.com/tracks/{}.json'.format(i)
            html = requests.get(murl, headers=headers1).text
            dic = json.loads(html)
            col2.insert(dic)
            print(murl + '中的数据已被成功插入mongodb')
    
    
    if __name__ == '__main__':
        get_url()

    7.如果改成异步的形式可以快一点,只需要修改成下面这样就行了。我试了每分钟要比普通的多获取近100条数据。这个源代码也在github中。


    异步

    五:总结

    这次抓取的数据量在70万左右,这些数据后续可以进行很多研究,比如播放量排行榜、时间区段排行、频道音频数量等等。后续我将继续学习使用科学计算和绘图工具来进行数据分析,清洗的工作。

    学习过程中遇到什么问题或者想获取学习资源的话,欢迎加入学习交流群
    626062078,我们一起学Python!

  • 相关阅读:
    C++学习笔记----2.4 C++对象的内存模型
    C++学习笔记(2)---2.5 C++函数编译原理和成员函数的实现
    C++学习笔记(1)-构造函数与析构函数
    学习笔记(5)---数学运算
    学习笔记(4)---协方差和特征向量的意义
    学习笔记(3)---安装SVM问题及解决方法
    学习笔记(2)---Matlab 图像处理相关函数命令大全
    数据增删查改操作总结
    表操作总结
    touch命令修改时间
  • 原文地址:https://www.cnblogs.com/jiaoyu121/p/7045746.html
Copyright © 2011-2022 走看看