爬虫简单一之获取酷狗top500名歌曲的名字,作者,排名,时间。并存入txt,csv,mysql。 - Go语言中文社区

爬虫简单一之获取酷狗top500名歌曲的名字,作者,排名,时间。并存入txt,csv,mysql。


爬虫简单一之获取酷狗top500名歌曲的名字,作者,排名,时间。并存入txt,csv,mysql。

准备使用环境为Python3.6+csv+time+requests+beautifulsoup+os+pymysql

环境说明 安装所要使用的库,使用库的说明

1.准备URL

打开https://www.kugou.com/yy/rank/home/1-8888.html?from=rank只能显示前22名
在这里插入图片描述

从图中看出的是只显示前22名,需要更多内容要下载客户端,但是通过改变1-8888.html中的数字1可以访问排行的前500名,一共需要24页。(他们后端可能并没有屏蔽其他的连接,仍然是可以访问的)

2.使用beautifulsoup的selector来获取所需要的具体内容,如歌手,歌名,歌曲时间等信息。(下面提供了一个简单而快捷的方法)

2.1右击要选取的元素内容,点击检查可以看到具体的源代码中的具体位置

在这里插入图片描述

在这里插入图片描述

2.2再右击要选取的元素,选中copy会出现很多选项,常用的有copy selector和copy xpath,copy selector是使用beautifulsoup中的selector方法来选取元素时要使用的,而copy xpath是使用lxml库时使用xpath方法时使用的,使用这一个方法可以提高代码的生产效率。本文使用的是beautifulsoup的selector方法。在这里插入图片描述

2.3下面是使用selector的具体代码(先使用beautiful soup来封装一下text再使用selector方法来选取。通过一下几行代码就可以把排名,名字,时间和歌手选取出来(歌手的名字和歌曲的名字在一个标签中使用-来分隔,选取出来之后可以使用split方法对字符串进行切分)。

html = requests.get(url, headers=headers)
    soup = BeautifulSoup(html.text, 'lxml')
    ranks = soup.select('#rankWrap > div.pc_temp_songlist > ul > li > span.pc_temp_num')
    names = soup.select('#rankWrap > div.pc_temp_songlist > ul > li > a')
    times = soup.select('#rankWrap > div.pc_temp_songlist > ul > li > span.pc_temp_tips_r > span')

源代码中的使用-连接的歌曲名个歌手名

在这里插入图片描述

分隔分别选出来的歌手名字和歌曲名字

name = names[i].get_text().strip().split('-')[1]
        signer = names[i].get_text().strip().split('-')[0]

3.当得到所有的信息之后,接下来就是要存储到文件当中,可以使用txt,csv,mysql等文件进行存储。

3.1存储到txt中(在存储到txt文件中时,使用的当写入时,只能写入一个元素,所以要把所有元素使用+号来连接起来再使用f.write()来存储到txt中去)
# 封装成函数
def write_txt(message):
    with open('../tmp/_02_kugou/kuGou.txt', 'a+') as f:
        f.write(message + 'n')

# 在进行调用时要使用加号把多个元素连接
write_txt(rank + name + signer + time1)

3.2存储到csv中首先open()函数打开当前路径下的名字为…/tmp/_02_kugou/kuGou.csv的文件,如果不存在这个文件,则创建它,返回f文件对象。csv.writer(f)返回writer对象csv_writer。writerow()方法是一行一行写入,writerows方法是一次写入多行。
def write_csv(rank, name, signer, time1):
    with open('../tmp/_02_kugou/kuGou.csv', 'a+') as f:
        csv_writer = csv.writer(f)
        csv_writer.writerow([rank, name, signer, time1])
3.3存储到mysql中,使用pymysql的connect方法传入多个参数之后连接数据库,创建一个游标,使用游标来执行sql语句,把获取到的值存储到数据库中。
def writer_mysql(rank, name, signer, time1):
    con = pymysql.connect(user='root', password='root', db='spider', host='localhost', port=3306, charset='utf8')
    cursor = con.cursor()
    try:
        sql = '''INSERT INTO kugou(rank, name, signer, time) VALUES('%d', '%s', '%s', '%s')'''
        cursor.execute(sql % (int(rank), name, signer, pymysql.escape_string(time1)))
        con.commit()
    except pymysql.err.IntegrityError:
        pass
    cursor.close()
    con.close()
注意在向mysql存储数据的时候出现 pymysql.err.ProgrammingError: 1064 (Python字符串转义问题)时

使用模块MySQLdb自带的针对mysql的字符转义函数 escape_string把要存储的元素转义一下如

        cursor.execute(sql % (int(rank), name, signer, pymysql.escape_string(time1)))

如果还是出现pymysql.err.ProgrammingError: 1064 错误就使用三引号’‘’ 来括取sql语句。应该就可以解决这个错误了

sql = '''INSERT INTO kugou(rank, name, signer, time) VALUES('%d', '%s', '%s', '%s')'''
        cursor.execute(sql % (int(rank), name, signer, pymysql.escape_string(time1)))
4.定义一个main函数,迭代所有的要爬取的URL链接,给爬虫函数传入链接,运行爬虫,作为一个文明的人,最好爬虫一次使用time.sleep()休息一段时间,一是为了不给服务器造成很大的客流量,二是爬虫过快,封禁ip等因素导致爬虫失败。
if __name__ == '__main__':

    urls = ['https://www.kugou.com/yy/rank/home/' + str(i) + '-8888.html' for i in range(1, 24)]
    for url in urls:
        print(url)
        get_message(url)
        time.sleep(5)

5.完整代码
import csv
import time
import requests
from bs4 import BeautifulSoup
import os
import pymysql

if not os.path.exists('../tmp/_02_kugou'):
    os.makedirs('../tmp/_02_kugou')

headers = {
    'User-Agent': 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.86 Safari/537.36',

}


def get_message(url):
    html = requests.get(url, headers=headers)
    soup = BeautifulSoup(html.text, 'lxml')
    ranks = soup.select('#rankWrap > div.pc_temp_songlist > ul > li > span.pc_temp_num')
    names = soup.select('#rankWrap > div.pc_temp_songlist > ul > li > a')
    times = soup.select('#rankWrap > div.pc_temp_songlist > ul > li > span.pc_temp_tips_r > span')
    # print(len(ranks))
    for i in range(0, len(ranks)):
        rank = ranks[i].get_text().strip()
        name = names[i].get_text().strip().split('-')[1]
        signer = names[i].get_text().strip().split('-')[0]
        time1 = times[i].get_text().strip()
        write_txt(rank + name + signer + time1)
        write_csv(rank, name, signer, time1)
        writer_mysql(rank, name, signer, time1)
        # print(rank, name, signer, time1)


def write_txt(message):
    with open('../tmp/_02_kugou/kuGou.txt', 'a+') as f:
        f.write(message + 'n')


def write_csv(rank, name, signer, time1):
    with open('../tmp/_02_kugou/kuGou.csv', 'a+') as f:
        csv_writer = csv.writer(f)
        csv_writer.writerow([rank, name, signer, time1])


def writer_mysql(rank, name, signer, time1):
    con = pymysql.connect(user='root', password='root', db='spider', host='localhost', port=3306, charset='utf8')
    cursor = con.cursor()
    try:
        sql = '''INSERT INTO kugou(rank, name, signer, time) VALUES('%d', '%s', '%s', '%s')'''
        cursor.execute(sql % (int(rank), name, signer, pymysql.escape_string(time1)))
        con.commit()
    except pymysql.err.IntegrityError:
        pass
    cursor.close()
    con.close()


if __name__ == '__main__':

    urls = ['https://www.kugou.com/yy/rank/home/' + str(i) + '-8888.html' for i in range(1, 24)]
    for url in urls:
        print(url)
        get_message(url)
        time.sleep(5)

欢迎加入公众号交流学习,该公众号会发布爬虫,数据分析和后端的知识

在这里插入图片描述

版权声明:本文来源CSDN,感谢博主原创文章,遵循 CC 4.0 by-sa 版权协议,转载请附上原文出处链接和本声明。
原文链接:https://blog.csdn.net/qq_42169061/article/details/90301908
站方申明:本站部分内容来自社区用户分享,若涉及侵权,请联系站方删除。

0 条评论

请先 登录 后评论

官方社群

GO教程

猜你喜欢