经常在网易云听歌,感觉那些人的文采不错,自古评论出人才,同时我又想了解到底是那些歌让这些人发挥出自己的才华。我们就爬取一些热歌的评论。
我们会用到的一些模块
from Crypto.Cipher import AES 加密
from base64 import b64encode 编码解码
import requests,json 请求 json语句
import re 正则表达式
from lxml import etree 数据的爬取
import pymysql 数据库操作
数据库的连接
db = pymysql.connect(host="localhost",
port=3306,
user="root",
passwd="123456",
database="wypc",
charset="utf8",
autocommit=True)
通过对网页源码的分析得到参数有两个,一个是params,一个是encSecKey并且都是经过加密的,我们就要分析它的源头。F12打开source搜索encSckey. 在查找这个js内部的encSecKey,找到encSecKey的位置,经过断点调试发现这里就是最终参数的结果,然后对json函数分析得到网易云网站的加密方式。对于数据爬取的过程,同样对网页得到了网页的请求方式和请求标头。先调用基本的requests库和json库以模拟网页对服务器请求功能和将爬取的html文件编码成json格式,调用re库以便对后面获取的列表进行正则解析。在本项目的代码中,我先是用get请求方式获取歌名id的列表,然后用一个response去接受request请求。并且使用了etree预处理数据。然后用xpath获取解析得的数据。
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/95.0.4638.54 Safari/537.36 Edg/95.0.1020.40'
}
f = "00e0b509f6259df8642dbc35662901477df22677ec152b5ff68ace615bb7b725152b3ab17a876aea8a5aa76d2e417629ec4ee341f56135fccf695280104e0312ecbda92557c93870114af6c9d05c4f7f0c3685b7a46bee255932575cce10b424d813cfe4875d3e82047b97ddef52741d546b8e289dc6935b3ece0462db0a22b8e7"
g = "0CoJUm6Qyw8W8jud"
e = "010001"
i = "oStLTrr0FaYKC6IE"
def get_encSecKey():
return "bf0c12e363f8fca9793ddab0cf6e1ea72b5d1c84c136a11147ce1b8b25da43ba385a7df0b5c97f0f9fe8904a23e318757cef5b8fe9da78ba447bfffc89a3fd3fc99db34631b69dffabe2bf6849961452f751fc71302bc3259177f70b4fdbf9ae19a5bd58b1d8422f4f0c1319f32099cbf6bf871bf59e459f05247c009f0f41f5"
def get_params(data): #默认这里收到的是字符串
first = enc_params(data,g)
second = enc_params(first, i)
return second
def to_16(data):
pad = 16 - len(data)%16
data += chr(pad)*pad
return data
def enc_params(data,key):
iv = "0102030405060708"
data = to_16(data)
aes = AES.new(key = key.encode("utf-8"),IV = iv.encode('utf-8'),mode = AES.MODE_CBC)
bs = aes.encrypt(data.encode("utf-8"))
return str(b64encode(bs),"utf-8")
url_song = 'https://music.163.com/discover/toplist?id=3778678'
resp = requests.get(url=url_song, headers=headers).text
tree = etree.HTML(resp)
song = tree.xpath('//div[@data-key="song_toplist-3778678"]/ul[@class="f-hide"]/li/a/@href')
song_name = tree.xpath('//div[@data-key="song_toplist-3778678"]/ul[@class="f-hide"]/li/a/text()')
obj = re.compile(r'\d+', re.S)
songID_list = []
在navicat创建表
写一个sql语句,通cursor.execute(sql)进行执行,我们的数据库的表实在另一个软件navicat已经建好,所以我能们的sql语句中只有插入的代码,db.commit() 来判断是否都插入成功,成功将结果提交给数据库。
for hot in range(0,Comment_mum):
nickname = result['data']['hotComments'][hot]['user']['nickname']
songName = song_name[song_count1]
hot_comment = result['data']['hotComments'][hot]['content']
if result['data']['hotComments'][hot]['user']['vipRights'] == None:
Vip = 0
else:
Vip = 1
likedCount = result['data']['hotComments'][hot]['likedCount']
sql = "insert into comment(ID,nickName,songName,comment,VIP,likedNum) " \
"values(%d,'%s','%s','%s',%d,%d)" % (comment_count, nickname, songName, hot_comment, Vip, likedCount)#sql语句
try:
cursor.execute(sql)#执行sql语句
db.commit() # 都插入成功,将结果提交给数据库
print(str(comment_count)+' 歌曲:“'+songName+'”的评论信息'+'已经存入MYSQL数据库!!!')
except Exception as e:
db.rollback()# 如果提交失败,结果回退到上一次提交的结果
print("执行MySQL时出错:%s" %e)
comment_count = comment_count + 1
song_count1 = song_count1 + 1 # 递增歌曲的名称
cursor.close()#关闭
db.close()#断开