requests爬取百度音乐

requests爬取百度音乐

 

使用requests爬取百度音乐,我想把当前热门歌手的音乐信息爬下来。

首先进行url分析,可以看到:

歌手网页:

<span>requests爬取百度音乐</span>

薛之谦网页:

<span>requests爬取百度音乐</span>

可以看到,似乎这些路劲的获取一切都很顺利,然后可以写代码:

# -*- coding: utf-8 -*-
"""
Created on Sat Dec 30 14:18:33 2017

@author: 24630
"""

import requests
from lxml import etree
import urllib.parse as urlparse

# 获得热门的前几个有封面的歌手
def get_info_artist(url):
    html = requests.get(url).text
    html=etree.HTML(html)
    hotlist = html.xpath('//div[@class="hot-head clearfix"]/dl/dd/a[1]/@href')    
    return hotlist

def get_info_single(url):
    html = requests.get(url).text
    html=etree.HTML(html)
    songlist = html.xpath('//div[@class="song-item"]//span[@class="song-title "]/a[1]/text()') 
    albumlist = html.xpath('//div[@class="song-item"]//span[@class="album-title"]/a[1]/text()') 
    downloadUrl = html.xpath('//div[@class="song-item"]//span[@class="song-title "]/a[1]/@href')
    
    #无法找到下一页的跳转连接
    #next_page = //div[@class="page-inner"]/a[last()]/text()
    print(len(songlist))
    


url = 'http://music.baidu.com/artist'
hotlist = get_info_artist(url)
#urljoin主要是拼接URL,
#它以base作为其基地址,
#然后与url中的相对地址相结合组成一个绝对URL地址。
#函数urljoin在通过为URL基地址附加新的文件名的方式来处理同一位置处的若干文件的时候格外有用。
#需要注意的是:
#如果基地址并非以字符/结尾的话,那么URL基地址最右边部分就会被这个相对路径所替换。
#如果希望在该路径中保留末端目录,应确保URL基地址以字符/结尾。

for u in hotlist:
    #获得单个歌手的链接
    url_singer = urlparse.urljoin(url,u)
    get_info_single(url_singer)

  可以看到,我读完一页后,想要继续进行下一页的数据的获取就没那么容易了。

<span>requests爬取百度音乐</span>

有时候显示:

<span>requests爬取百度音乐</span>

 

至于怎么获得下一页的信息:

<span>requests爬取百度音乐</span>

通过上面可以分析,上面三处有数据的地方分别是点击下一页的时候产生的,可以在上面找一下。

这个时候,可以分析到:

实际上,跳转路径的动态请求隐藏在:

<span>requests爬取百度音乐</span>

这样一个路径下。

因此,实际上可以构建该路径进行获取歌曲信息。

<span>requests爬取百度音乐</span>

可以看到,该路径下动态请求的页面是一个json格式数据,可以通过json解析,获取其中的html源码。

 

 代码修改为:

import requests
from lxml import etree
import urllib.parse as urlparse
import json,re,os
import sqlite3

def writeDB(song_dict):
    global num
    c = conn.cursor()
    sql = '''insert into baiduMusic (id, songName,singer,albumname,download) values (?,?,?,?,?)'''
    para = (num,song_dict['歌曲'],song_dict['歌手'],song_dict['专辑'],song_dict['下载路径'])
    c.execute(sql,para)
    conn.commit()
    num += 1


# 获得热门的前几个有封面的歌手
def get_info_artist(url):
    html = requests.get(url).text
    html=etree.HTML(html)
    hotlist = html.xpath('//div[@class="hot-head clearfix"]/dl/dd/a[1]/@href')    
    return hotlist

def get_info_single(url):
    re_com = re.compile('artist/(\d+)') 
    ting_uid = re_com.findall(url)[0]
    get_info_single_page(0,ting_uid)
    
def get_info_single_page(i,ting_uid):
    page = 'http://music.baidu.com/data/user/getsongs?start={0}&ting_uid={1}'.format(i,ting_uid)

    html = requests.get(page).text
    html = json.loads(html)["data"]["html"]
    html=etree.HTML(html)
    songlist = html.xpath('//div[@class="song-item"]//span[@class="song-title "]/a[1]/text()') 
    albumlist = html.xpath('//div[@class="song-item"]//span[@class="album-title"]/a[1]/text()') 
    downloadUrl = html.xpath('//div[@class="song-item"]//span[@class="song-title "]/a[1]/@href')
    try:
        singer = html.xpath('//div[@class="song-item"]//span[@class="song-title "]/a[1]/@title')[0]
        re_com = re.compile('(\S+?)《') 
    
        #这种解析歌手的方法不好,为了省事先这么弄的
        singer = re_com.findall(singer)[0]
    except:
        singer = ' '
    print(singer)
    for songName,album,download in zip(songlist,albumlist,downloadUrl):
        song_dict = {}
        song_dict['歌曲'] = songName
        song_dict['歌手'] = singer
        song_dict['专辑'] = album
        song_dict['下载路径'] = download
        writeDB(song_dict)
    #歌曲都获取全了,即获得某一页歌曲数少于25
    if (len(songlist) == 25):    
        get_info_single_page(i+25,ting_uid)



num = 1
if not os.path.isfile('test.db'):
    conn = sqlite3.connect('test.db')
    
    c = conn.cursor()
    c.execute('''create table baiduMusic (id integer primary key,songName varchar(10),singer varchar(10),
                                                   albumname varchar(10),
                                                   download varchar(10));''')
    conn.commit()
else:
    conn = sqlite3.connect('test.db')
url = 'http://music.baidu.com/artist'
hotlist = get_info_artist(url)
#urljoin主要是拼接URL,
#它以base作为其基地址,
#然后与url中的相对地址相结合组成一个绝对URL地址。
#函数urljoin在通过为URL基地址附加新的文件名的方式来处理同一位置处的若干文件的时候格外有用。
#需要注意的是:
#如果基地址并非以字符/结尾的话,那么URL基地址最右边部分就会被这个相对路径所替换。
#如果希望在该路径中保留末端目录,应确保URL基地址以字符/结尾。

for u in hotlist:
    #获得单个歌手的链接
    url_singer = urlparse.urljoin(url,u)
    get_info_single(url_singer)

conn.close()

  

 

最终获得效果:

<span>requests爬取百度音乐</span>

 

当然,上面的download链接是歌曲的跳转链接,如果需要下载的话,可以继续分析:

<span>requests爬取百度音乐</span>

如上,可以继续分析如何构建歌曲文件的url,然后完成下载。

 

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/119473.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • murmurhash算法_自我介绍的方式

    murmurhash算法_自我介绍的方式加密哈希和非加密哈希-MM是非加密哈希首先了解下加密哈希和非加密哈希,加密哈希函数旨在保证安全性,很难找到碰撞。即:给定的散列h很难找到的消息m;很难找到产生相同的哈希值的消息m1和m2。非加密哈希函数只是试图避免非恶意输入的冲突。作为较弱担保的交换,它们通常更快。如果数据量小,或者不太在意哈希碰撞的频率,甚至可以选择生成哈希值小的哈希算法,占用更小的空间。Smhasher-评价哈希算法的…

    2022年10月9日
    2
  • 基本稳压电路

    基本稳压电路经过整流后的电源具有较大的电压纹波,单靠调节滤波电容不能明显改善输出电源纹波特性,因此需要采用稳压电路来减小输出电源的纹波。若直将稳压管接至负载输出,则稳压管的工作特性受负载影响较大,甚至会出现不能正常工作的情况。采用下图所示的稳压电路则能保证稳压管始终能够正常工作。其核心思想仍然是负反馈。运放正输入端采用稳压管提供一个相对稳定的基准电压,并通过同相放大在输出端得到一个稳定的输出电压。而由于运放具有一定的电源抑制比,所以在供电电压在一定范围波动时,其仍可正常工作。同向比例运放的输出电流有限,故采用了

    2022年6月20日
    34
  • thinkphp使用PHPMailer发送邮件

    thinkphp使用PHPMailer发送邮件

    2021年9月21日
    41
  • SecureCRT中文乱码解决方法

    SecureCRT中文乱码解决方法SecureCRT中文乱码解决方法1、先选中当前的Session地址2、然后点击SercureCRT上排主菜单的“Options”,也就是“选项”的意思3、点击Options之后,会出现一个下拉列表,我们选择第一个“SessionOptions…”4、接着会出现一个弹出框,选择目录中的“Appearance”,该功能可以对SercureCRT的外观进行设置5、此时可以看到SercureCRT的编码格式是“Default”,也就是默认的编码格式,我们改为“UTF-8”6、改完编码格式之后,我们回

    2022年7月17日
    13
  • JAVA多线程中join()方法的详细分析

    JAVA多线程中join()方法的详细分析虽然关于讨论线程join()方法的博客已经非常极其特别多了,但是前几天我有一个困惑却没有能够得到详细解释,就是当系统中正在运行多个线程时,join()到底是暂停了哪些线程,大部分博客给的例子看起来都像是t.join()方法会使所有线程都暂停并等待t的执行完毕。当然,这也是因为我对多线程中的各种方法和同步的概念都理解的不是很透彻。通过看别人的分析和自己的实践之后终于想明白了,详细解释一下希望能帮助到…

    2022年4月28日
    37
  • matlab 伽马校正曲线,【图像处理知识复习】02伽马校正matlab,C++实现

    matlab 伽马校正曲线,【图像处理知识复习】02伽马校正matlab,C++实现1.背景:伽马校正可以用来调整图像的亮度,公式为I=I^gamma。当gamma>1,高光部分动态范围被压缩,低光部分动态范围被扩展(使低光部分的细节可以看清),图像整体变暗;当gamma<1,高光部分被扩展,低光部分被压缩,图像整体变亮。如图:2.matlab代码:clc;clear;gamma=0.3;img=imread(‘D:/Code/Image/half…

    2022年9月24日
    3

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号