工具:用到requests库和BeautifulSoup库,也就是bs4

学习爬取酷狗音乐TOP500 的排名,歌手-歌名,播放时间这些信息

网址为https://www.kugou.com/yy/rank/home/1-8888.html?from=rank

进入网页,在网址后面的部分可以看到有个1-8888

其实是网页端只能显示第一页,如果想看第几页那么直接把1改成几就可以

可以知道最后一页是23页

所以我们可以python遍历打印爬取到的信息

首先记下几个知识点

网址英文名url,唯一资源定位符,可以观察到 url 由如下几个部分组成

https:传输协议,一般都是 http 或 https

www.kugou.com:为域名

yy/rank/home/...:为域名下的子网页

.html:代表此网页是静态的,后面会讲

?:问好后面的一般都是一些请求参数

所以第一步构造所有的urls

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

构造请求头

什么是请求头?

因为现在爬虫技术越来越泛滥,有些网页会采取反爬取的手段。

因此我们设置请求头为浏览器的请求头,对方就会认为我们是人为的访问,从而不会反爬,这只是最简单的一种防反爬的手段

headers = {'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64)'
                             ' AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.100 Safari/537.36'}

这并不是无中生有,而是在浏览器开发者选项中能找到的,看图

python 爬虫酷狗音乐 爬取酷狗top500_python 爬虫酷狗音乐

请求访问网页

使用request库的get方法去访问网页,第一个参数为url,第二个为请求头,也就是header

get到的结果我们可以查看其请求状态码,200表示成功

也可以返回其text,即html源码

代码如下:

response = requests.get(url, headers=headers)
    if response.status_code == 200:
        return response.text
    else:
        return

解析网页HTML源码

我们需要结构化,便于提取

html = BeautifulSoup(html)

提取各类数据

CSS选择器

在开发者选项中,先查看一段内容的代码,在代码上点击右键,选择 Copy -> Copy Selector (或者 Copy CSS Selector、复制 CSS 选择器),就能将这段内容对应的 CSS 选择器复制到剪贴板。

比如我们要知道排名的css选择器

python 爬虫酷狗音乐 爬取酷狗top500_请求头_02

操作之后结果为

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

但是这只是一条数据,所以我们要把:nth-child(1)去掉

#rankWrap > div.pc_temp_songlist > ul > li > span.pc_temp_num

提取是用select方法来操作的

#排名
    ranks = html.select('#rankWrap > div.pc_temp_songlist > ul > li > span.pc_temp_num')
    #歌手+歌名
    names = html.select('#rankWrap > div.pc_temp_songlist > ul > li > a')
    #播放时长
    times = html.select('#rankWrap > div.pc_temp_songlist > ul > li > span.pc_temp_tips_r > span')

获得数据

用zip函数打包这三个数据

for r, n, t in zip(ranks, names, times):
        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函数的结果相当于一个列表,每个元素中又是一个序列(排名,歌手歌名,播放时长)

因为我们提取到的只是标签信息,所以我们要用到get_text()方法以获得实际数据

并且去掉其中多余的字符

最后把数据包装成字典形式然后打印

 

最终代码

import requests
import time
from bs4 import BeautifulSoup


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


def get_info(html):
    #提取数据
    html = BeautifulSoup(html)
    #排名
    ranks = html.select('#rankWrap > div.pc_temp_songlist > ul > li > span.pc_temp_num')
    #歌手+歌名
    names = html.select('#rankWrap > div.pc_temp_songlist > ul > li > a')
    #播放时间
    times = html.select('#rankWrap > div.pc_temp_songlist > ul > li > span.pc_temp_tips_r > span')

    #打印信息
    for r, n, t in zip(ranks, names, times):
        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_info(html)
        time.sleep(1)


main()

最终的输出的结果为

python 爬虫酷狗音乐 爬取酷狗top500_python 爬虫酷狗音乐_03