上一篇介绍了爬网易云歌手id, 在这里我们可以用获取的id数据来构造歌手详情页的url。在这里呢我还是比较习惯使用selenium来爬。
简单介绍一下selenium:
它是浏览器的一个自动化测试框架,运行在浏览器中模拟人操作浏览器,支持Mozilla Firefox,Ie,Google Chrome,Safari,Opera等浏览器。在这里笔者用的是Chrome 72,使用里边的webdriver模块,可以加载出网页所有的源码,包括使用Ajax技术加载的网站,解决JavasScript渲染的问题。
参考:https://github.com/easonhan007/webdriver_guide/blob/master/README.md
很多的HTTP请求都带有参数,然而这些参数有时候是经过各种加密,相对于解密我倾向于直接使用驱动浏览器直接获取源码(悄悄地偷个懒),当然望网上也有很多直接从请求入手,抓包分析js代码了解加密方式进而解密抓取信息。这种方式也可行。
导一下需要用到的模块,因为要构造出url首先要先读出来我们获取的歌手id,并且把id放进数组方便后期使用。
from selenium import webdriver
from bs4 import BeautifulSoup
import csv
import time
id = open('F:/music/网易云歌手id.csv', 'r', encoding='utf-8-sig')
id_reader = csv.DictReader(id)
columns = [row['id'] for row in id_reader]
然后就是要打开浏览器,浏览器打开的时候可以是无界面的,当然可以设置成有界面。
# 打开浏览器
option = webdriver.ChromeOptions()
option.add_argument('--headless')
driver = webdriver.Chrome(options=option)
#有界面
#driver = webdriver.Chrome()
#driver.get(url)
接下来是歌曲的详情使用BeautifulSoup:
# 歌曲详细信息
for song_id in columns:
song_names = []
song_times = []
song_edits = []
song_ids = []
url = 'https://music.163.com/#/artist?id='+str(song_id)
driver.get(url)
time.sleep(5)
driver.switch_to.frame('g_iframe')
code = driver.page_source
soup = BeautifulSoup(code, 'lxml')
songs = soup.find_all('span', class_='txt')
# 歌曲id
for songlinks in songs:
song_link = songlinks.a['href'].replace('/song?id=', '')
song_ids.append(song_link)
#print(song_ids)
#print(len(song_ids))
# 歌曲名字
for song in songs:
song_name = song.b['title']
song_names.append(song_name)
#print(song_names)
#print(len(song_names))
# 歌曲时间
times = soup.find_all('span', class_='u-dur')
for tim in times:
song_time = tim.text
song_times.append(song_time)
#print(song_times)
#print(len(song_times))
#歌曲专辑
edits = soup.find_all('div', class_='text')
for edit in edits:
song_edit = edit.a['title']
song_edits.append(song_edit)
#print(song_edits)
#print(len(song_edits))
遍历数组写入文件:
#写入文件
try :
for j in range(0, len(song_ids)):
wr.writerow([song_ids[j], song_names[j], song_times[j], song_edits[j]])
except Exception as e:
print(e)
i = i+1
print('第'+str(i)+'次执行完毕')
笔者写的不好还请小伙伴们多多指教哦
未完待续…请关注下一篇网易云音乐评论。