Python爬取酷狗音乐TOP500榜单

最近参加了一个数据挖掘比赛,所以一边比赛,一边学Python/(ㄒoㄒ)/~~,相比被算法折磨的死去活来,python就很友好了(●'◡'●),学了点基础就直接应用了。废话不多说直接开始。

环境配置

我们用到的是 bs4,requests,lxml这三个库来提取,其中bs4是简称,全称是 BeautifulSoup4.0 库。中文名也叫“美丽的汤”,安装也很简单。
打开 cmd 命令行(win + r),输入 pip install bs4 完成安装。pip是一个通用的 Python 包管理工具。提供了对Python 包的查找、下载、安装、卸载的功能。
其他两个库同理。成功会提示Successfully installed xxx。

构造请求头

我们需要安装Chrome浏览器,进入浏览器 Ctrl+Shift+I 呼出开发者工具。接着打开网址:https://www.kugou.com/yy/rank/home/1-8888.html?from=rank ,找到如图所示的User-Agent
什么是请求头?
别人网页区别是人还是机器访问的一种手段,我们设置请求头为浏览器的请求头,对方就会认为我们是人为的访问,从而不会反爬,当然这只是最简单的一种防反爬的手段,一般我们都会带上,代码如下:
'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.108 Safari/537.36'
后面代码会用到。

请求访问网页

def get_html(url):
    headers = {'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) '
                             'AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.108 Safari/537.36'
    }
    response = requests.get(url,headers=headers)
    if response.status_code == 200:
        return response.text
    else:
        return

response = requests.get(url, headers=headers)

使用 requests 库的 get 方法,去访问网页,第一个参数为网址,第二个参数为请求头,请求结果赋值给变量 response,其中里面有很多结果,状态响应码,网页源码,二进制等

response.status_code == 200

调用请求结果 response 中的 status_code 查看请求状态码,200 代表请求成功,就返回,否则返回一个 None,状态码一般有 2xx,4xx,3xx,5xx,分别代表请求成功,客户端访问失败,重定向,服务器问题。

return response.text

返回响应结果的 text,代表返回网页 html 源码

解析网页

返回了html源码后,我们需要解析网页 html 源码,需要结构化,便于提取数据。

html = BeautifulSoup(html,"lxml") //"lxml"是解析器。

获取数据

选择要提取数据,右键检查。

#rankWrap > div.pc_temp_songlist > ul > li:nth-child(1) > span.pc_temp_num

其中 li:nth-child(1) 需要改成 li,因为 nth-child(1) 是获取 li 标签下的一条数据,我们是要获取这一页的所有排名。
其他数据同理,得到如下代码。

    ranks = html.select('#rankWrap > div.pc_temp_songlist > ul > li > span.pc_temp_num')
    name = html.select('#rankWrap > div.pc_temp_songlist > ul > li > a')
    time = html.select('#rankWrap > div.pc_temp_songlist > ul > li > span.pc_temp_tips_r > span')

整合数据

    for r,n,t in zip(ranks,name,time):
        r = r.get_text().replace('\n','').replace('\t','').replace('\r','')
        n = n.get_text()
        t = t.get_text().replace('\n','').replace('\t','').replace('\r','')

用了 zip 函数,意思是把对应的排名,歌名歌手,播放时间打包,可以这样理解 zip 函数的结果是一个列表 [(排名,歌手歌名,播放时间)。
每一次循环的 r,n,t 一次对应元组中的元素

get_text()

我们提取到的是这个数据所在的标签信息,并不是实际数据,所以需要使用 get_text() 获得实际数据

.replace('\n','').replace('\t','').replace('\r','')

去掉实际数据中多余的字符串,最后把数据打包成字典打印。

End!

大体思路到这里就结束了,很多地方用了Python123的专栏。非常感谢原文的作者!!!

[1]木下瞳的专栏,https://python123.io/python/muxiatong/5dd14d1b71efdc10be55ee22

完整代码

#酷狗TOP500
import time
import requests
from bs4 import BeautifulSoup

def get_html(url):
    headers = {'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) '
                             'AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.108 Safari/537.36'
    }
    response = requests.get(url,headers=headers)
    if response.status_code == 200:
        return response.text
    else:
        return

def get_infos(html):

    html = BeautifulSoup(html,"lxml")
    ranks = html.select('#rankWrap > div.pc_temp_songlist > ul > li > span.pc_temp_num')
    name = html.select('#rankWrap > div.pc_temp_songlist > ul > li > a')
    time = html.select('#rankWrap > div.pc_temp_songlist > ul > li > span.pc_temp_tips_r > span')
    for r,n,t in zip(ranks,name,time):
        r = r.get_text().replace('\n','').replace('\t','').replace('\r','')
        n = n.get_text()
        t = t.get_text().replace('\n','').replace('\t','').replace('\r','')
        data ={
            '排名': r,
            '歌名-歌手': n,
            '播放时间': t
        }
        print(data)

def main():
    urls =['https://www.kugou.com/yy/rank/home/{}-8888.html?from=rank'.format(str(i))for i in range(1,24)]
    for url in urls:
        html = get_html(url)
        get_infos(html)
        time.sleep(1)

#if __name__ == '_main_':
if __name__ == '__main__':
    main()

猜你喜欢

转载自www.cnblogs.com/lijiaji/p/12008563.html