一、数据库部分
- 此次关于涉及到的主要是数据库的创建、表的创建、数据的插入以及数据的查询四部分。
- 数据库的创建:
db=pymysql.connect(host='localhost',user='****',password='********',port=3306) cursor=db.cursor() cursor.execute('create database rdc_test default character set utf8')复制代码
- 首先通过pymysql的connect()方法声明一个mysql连接对象db,由于mysql在本地运行,所以传入的host(即IP)为localhost,后续参数依次输入用户名,密码,端口号。
- 接着通过db.cursor()方法获得mysql的操作游标
- 最后通过execute()方法调用SQL语句:创建一个名为rdc_test的数据库,默认编码为UTF-8(注意创建的时候不需要'-')
- 表的创建:
db = pymysql.connect(host='localhost', user='****', password='********', port=3306, db='rdc_test') cursor=db.cursor() sql='create table music(song varchar(255),singer varchar(255),id varchar(255))' cursor.execute(sql) db.close()复制代码
- 首先,连接本地已创建的名为rdc_test的数据库
- 接着,获得操作游标以便后续操作
- 接着,调用SQL语句,以column_name data_type(size)的形式创建表
- 最后关闭数据库
- 数据的插入:
db = pymysql.connect(host='localhost', user='****', password='********', port=3306, db='rdc_test') cursor = db.cursor() sql='insert into music(song,singer,id) values(%s,%s,%s)' try: cursor.execute(sql,(song,singer,id)) db.commit() except: db.rollback() db.close()复制代码
- 首先老套路,连接数据库,获得操作游标
- 接着,通过SQL语句插入数据,注意,此处注意用%s构造SQL语句,后面只需要在execute()中第一个参数传入SQL语句,第二个参数传入对应数据的元组就好了,这样写避免了拼接字符串的麻烦,又避免了引号导致的错误
- 接着,调用commit()方法将插入语句提交到数据库执行
- 此处进行了异常处理,如果数据插入失败,则执行数据回滚
- 最后关闭数据库
- 数据的查询:
db = pymysql.connect(host='localhost', user='root', password='password', port=3306, db='rdc_test') cursor = db.cursor() sql='select * from music where id="{}"'.format(id) if cursor.execute(sql): return 0 else: return 1复制代码
- 首先老套路,连接数据库,获取操作游标
- 接着,通过SQL语句查询目标id在表中是否存在,若存在,返回0,否则返回1,以便后续函数处理
- 注意查询语句的执行不需要调用commit()方法
二、QQ音乐的爬取
- 首先观察打开下载歌曲的连接,发现:
downloader_url = 'http://dl.stream.qqmusic.qq.com/C400{}.m4a?vkey={}&guid=8208467632&uin=0&fromtag=66'复制代码
- 这里两个参数是变化未知的,第一个可以由C400+songmid构成,但是第二个参数vkey应该怎么获得呢?
- 接着我们发现,在
fcg_url = 'https://c.y.qq.com/base/fcgi-bin/fcg_music_express_mobile3.fcg?g_tk=5381&jsonpCallback=MusicJsonCallback9239412173137234&loginUin=0&hostUin=0&format=json&inCharset=utf8&outCharset=utf-8¬ice=0&platform=yqq&needNewCode=0&cid=205361747&callback=MusicJsonCallback9239412173137234&uin=0&songmid={}&filename=C400{}.m4a&guid=8208467632'复制代码
- 这个链接得到的json数据中就含有vkey,仔细分析这个链接,发现有两个未知的参数,第一个是songmid,第二个是C400+songmid构成
- 也就是说,现在我们只要能获得songmid,爬取QQ音乐便指日可待:
search_url='https://c.y.qq.com/soso/fcgi-bin/client_search_cp?t=0&aggr=1&cr=1&catZhida=1&lossless=0&flag_qc=0&p=1&n=10&w={}&g_tk=5381&loginUin=0&hostUin=0&format=json&inCharset=utf8&outCharset=utf-8¬ice=0&platform=yqq.json&needNewCode=0'复制代码
- 我们发现,这个链接中有着包括songmid在内的歌曲的各种信息,而唯一变化的参数w后面跟着的就是我们的搜索内容。
三、tkinter界面的制作
- 关于这部分,主要就是调整组件的布局
- 其次,通过按钮的command参数关联相关的函数
- 最后,可以用listbox显示所爬取的歌曲列表,这样,通过curselection()方法可以获得目标下载歌曲的默认索引,通过这个索引最终达到正确下载对应歌曲的目的
四、网易云的爬取
- 首先,由于我的python是3.7版本,所以光是为了下载模拟AES加密的Crypto第三方库就浪费了好多时间……
- 其次,由于就我目前的能力,网易云的加密实在太过逆天……所以都是翻博客学着爬下来的
- 总的来说,网易云的请求都是Post方法,而相关的data参数都是params和encSecKey。
- 通过寻找,我们发现params其实就是相关变量的encText,encSecKey对应相关变量的encSecKey,而这个变量是通过window.asrsea这个函数获得的,这个函数有四个参数,经过对比检查,我们发现后面三个参数是固定值,而第一个参数,在搜索歌曲名获得搜索列表和获取下载链接时,其内容分别是:
first_param='{"hlpretag":"","hlposttag":"","id":"","s":"' + keyword + '","type":"1","offset":"0","total":"true","limit":"100","csrf_token":""}'song_params='{"ids": "[' + str(id) + ']","br":128000,"csrf_token":""}'复制代码
-
所以剩下的问题就是window.asrsea函数的函数体是什么?
-
我们发现,window.asrsea函数其实就是d函数,函数a产生了一个随机的16位数,函数b实现了AES加密,函数c实现了RSA加密,也就是说:encText是经过两次AES加密形成的,encSecKey是经过一次RSA加密形成的
-
此处注意,函数c的三个参数中,后面的e、f两个参数是固定的,只有第一个参数i的变化的,而这个i是由a函数产生的16位随机数,那我们换一个角度想一想,既然是随机数是随机产生的,那么每次产生的随机数都相同这种情况出现的几率虽然小,但还是存在的吧?既然如此,我们可以取一个最简单的16位随机数,把这个随机数固定下来,通过这种做法,i就变成了一个常量,从而encSecKey也就是一个常量了。通过这种转换,可以免去编写RSA加密的代码,使得程序更加简单
五、词云部分
待实现,还在学习当中嘻嘻嘻嘻嘻