Python爬蟲實(shí)戰(zhàn)分析:如何使用Selenium爬取QQ音樂歌曲+評(píng)論信息?

本文對(duì)使用到的技術(shù)僅做簡(jiǎn)單的介紹,若想了解更多,請(qǐng)前往相應(yīng)的官網(wǎng)網(wǎng)站進(jìn)行學(xué)習(xí)。 本文適合對(duì)爬蟲相關(guān)知識(shí)接觸不多的新手,主要是普及Selenium如何做爬蟲,大佬請(qǐng)?zhí)^。

01 Selenium簡(jiǎn)單介紹

1.1.簡(jiǎn)介

  • Selenium是一個(gè)用于測(cè)試網(wǎng)站的自動(dòng)化測(cè)試工具,支持各種主流界面瀏覽器。

  • 簡(jiǎn)而言之,Selenium是一個(gè)用來做網(wǎng)站自動(dòng)化測(cè)試的庫(kù),它的定位是做自動(dòng)化測(cè)試的。我們也可以利用它來做爬蟲,獲取一些網(wǎng)頁(yè)信息,并且這種爬蟲是模擬真實(shí)瀏覽器操作的,實(shí)用性更強(qiáng)。

  • Selenium是市面上唯一一款可以與付費(fèi)產(chǎn)品競(jìng)爭(zhēng)的自動(dòng)化測(cè)試工具。

  • 如果想了解更多,可以前往Selenium中文網(wǎng)學(xué)習(xí)

1.2.安裝

  • 要使用Selenium首先要在python中安裝相關(guān)的庫(kù):

pip install Selenium

  • 安裝相應(yīng)瀏覽器的webdricer驅(qū)動(dòng)文件,這里提供chrome的鏈接,其它瀏覽器網(wǎng)上搜一搜就有。選擇合適的版本,我選擇的是2.23。

  • 下載解壓后得到exe文件,將這個(gè)文件拷貝到chrom的安裝文件夾下:

  • 一般是C:\Program Files (x86)\Google\Chrome\Application,或者是C:\Program Files\Google\Chrome\Application。

image
  • 然后將該路徑配置到環(huán)境變量中:
image
  • 最后到寫段代碼測(cè)試一下:

from selenium import webdriver
driver=webdriver.Chrome(executable_path="C:\Program Files (x86)\Google\Chrome\Application\chromedriver.exe")

如果看到開啟了一個(gè)瀏覽器窗口就是成功了,否則下面會(huì)有相應(yīng)的報(bào)錯(cuò)信息,需要檢查前面的步驟。

1.3.簡(jiǎn)單使用介紹

1.元素定位方式:

image.png
  • 基本上前幾種方式就能夠獲取到需要的元素,需要自己辨別結(jié)果是否唯一來選擇相應(yīng)的選擇器。

  • 通過drive對(duì)象調(diào)用此方法,返回的是標(biāo)簽對(duì)象,或者是標(biāo)簽對(duì)象的列表,可以通過.text獲取該標(biāo)簽下的文字,可以通過get_attribute()獲取標(biāo)簽的其它屬性值。

分享快速定位元素的小妙招:看所需信息所在的標(biāo)簽的id,class,name的名稱是否與標(biāo)簽下信息的語(yǔ)義有關(guān),一般有關(guān)的都代表是唯一的。(從開發(fā)者的角度去思考)若無法通過當(dāng)前標(biāo)簽唯一定位,則考慮父級(jí)標(biāo)簽,一次類推,總是能找到定位的方法的。

2.鼠標(biāo)事件(模擬鼠標(biāo)操作)

image.png
  • 通過標(biāo)簽對(duì)象調(diào)用即可。

3.鍵盤事件(模擬鍵盤操作)

image.png

4.其他操作

  • 其他操作包括控制瀏覽器的操作,獲取斷言信息,表單切換,多窗口切換,警告框處理,下拉框處理,文件上傳操作,cookie操作,調(diào)用js代碼,截圖,關(guān)閉瀏覽器等操作,因?yàn)樵谶@里用的不多,就沒有一一羅列,自行去官網(wǎng)學(xué)習(xí)。

02 爬取目標(biāo)

  • 這個(gè)實(shí)戰(zhàn)爬蟲主要完成以下目標(biāo):

  • 爬取QQ音樂官網(wǎng)指定歌手的前5首歌曲的基本信息和前五百條熱門評(píng)論。

image
image
image

2.1 獲取前五歌曲的url

  • 分析該頁(yè)面的代碼得知,包裹所有歌曲信息的標(biāo)簽的class是唯一的,我們可以獲取到它,再遍歷所有子標(biāo)簽,也可以一次得到所有包裹歌曲信息的div,再獲取里面的a標(biāo)簽。
image.png

2.2 獲取歌曲基本信息

  • 可以看到基本信息標(biāo)簽里的class名稱是有一部分帶語(yǔ)義的,那么通過css選擇器肯定可以唯一確定下來。
image.png

2.3 獲取歌詞

  • 頁(yè)面上的歌詞不完整,似乎需要點(diǎn)擊展開才行,但其實(shí)所有歌詞已經(jīng)在標(biāo)簽里面了,只是顯示的問題了。
image

2.4 獲取前五百條評(píng)論消息

  • 我們可以看到熱門評(píng)論一次是十五條,下面有一個(gè)點(diǎn)擊加載更多鏈接,點(diǎn)了之后會(huì)多出15條。

  • 我們需要模擬點(diǎn)擊33次,獲得510條評(píng)論

image

2.5 寫入CSV文件

使用csv庫(kù),將爬取到的數(shù)據(jù)寫入到csv文件中進(jìn)行持久化。

2.6 實(shí)現(xiàn)代碼


from selenium import webdriver
import csv
from time import sleep
import time
#
#  Author : ATFWUS
#  Date : 2021-03-21 20:00
#  Version : 1.0
#  爬取周杰倫最熱門五首歌曲的基本信息,歌詞,前五百條熱門評(píng)論
#  此代碼僅供交流學(xué)習(xí)使用
#
#1.創(chuàng)建Chrome瀏覽器對(duì)象,這會(huì)在電腦上在打開一個(gè)瀏覽器窗口
driver=webdriver.Chrome(executable_path="C:\Program Files (x86)\Google\Chrome\Application\chromedriver.exe")
#2.打開QQ音樂 -周杰倫頁(yè)面
driver.get("https://y.qq.com/n/yqq/singer/0025NhlN2yWrP4.html")
#3.配置
csv_file = open('songs.csv','w',newline='',encoding='utf-8')
writer = csv.writer(csv_file)
start = time.time()
# 取前5首歌曲
song_numer=5
song_url_list=[]
song_resourses=[]
songlist__item=driver.find_elements_by_class_name("songlist__item")
# 獲取所有歌曲url
for song in songlist__item:
    song__url=song.find_element_by_class_name("js_song").get_attribute("href")
    song_url_list.append(song__url)
    song_numer-=1
    if(song_numer==0):
        break
# print(song_url_list)
print("已獲取周杰倫熱門歌曲列表前五首的url")
print()
# 獲取一首歌曲所需要的信息
def getSongResourse(url):
    song_resourse={}
    driver.get(url)
    # 這個(gè)0.5秒用于等待異步請(qǐng)求的完成
    sleep(0.8)
    # 獲取歌曲名
    song_name=driver.find_element_by_class_name("data__name_txt").text
    print("開始獲取歌曲《"+song_name+"》的基本信息")
    # 獲取流派,發(fā)行時(shí)間,評(píng)論數(shù)
    song_liupai = driver.find_element_by_css_selector(".js_genre").text[3:]
    song_time = driver.find_element_by_css_selector(".js_public_time").text[5:]
    song_comment_num = driver.find_element_by_css_selector(".js_into_comment").text[3:-1]
    print("歌曲《" + song_name + "》基本信息獲取完畢")
    print("開始獲取歌曲《" + song_name + "》的歌詞")
    # 點(diǎn)擊展開歌詞
    driver.find_element_by_partial_link_text("[展開]").click()
    sleep(0.3)
    lyic=""
    # 獲取拼接歌詞
    lyic_box=driver.find_element_by_id("lrc_content").find_elements_by_tag_name("p")
    for l in lyic_box:
        if l.text!="":
            lyic+=l.text+"\n"
    print("歌曲《" + song_name + "》的歌詞獲取完畢")
    print("開始獲取歌曲《" + song_name + "》的第1-15條熱門評(píng)論")
    # 獲取500條評(píng)論
    comments=[]
    # 點(diǎn)擊加載更多29次,每次多出15條評(píng)論
    for i in range(33):
        driver.find_element_by_partial_link_text("點(diǎn)擊加載更多").click()
        print("開始獲取歌曲《" + song_name + "》的第"+str((i+1)*15+1)+"-"+str((i+2)*15)+"條熱門評(píng)論")
        sleep(0.5)
    comments_list=driver.find_element_by_css_selector(".js_hot_list").find_elements_by_tag_name("li")
    for com in comments_list:
        content=com.find_element_by_css_selector(".js_hot_text").text
        content_time=com.find_element_by_css_selector(".comment__date").text
        zan_num=com.find_element_by_class_name("js_praise_num").text
        comment = {}
        comment.update({"評(píng)論內(nèi)容":content})
        comment.update({"評(píng)論時(shí)間":content_time})
        comment.update({"評(píng)論點(diǎn)贊次數(shù)":zan_num})
        comments.append(comment)
    print("歌曲《" + song_name + "》的前五百條熱門評(píng)論獲取完畢")
    print("歌曲《"+song_name+"》所有信息獲取完畢")
    print()
    song_resourse.update({"歌曲名":song_name})
    song_resourse.update({"流派":song_liupai})
    song_resourse.update({"發(fā)行時(shí)間":song_time})
    song_resourse.update({"評(píng)論數(shù)":song_comment_num})
    song_resourse.update({"歌詞":lyic})
    song_resourse.update({"500條精彩評(píng)論":comments})
    return song_resourse
for song_page in song_url_list:
    song_resourses.append(getSongResourse(song_page))
    # break
print("正在寫入CSV文件...")
for i in song_resourses:
    writer.writerow([i["歌曲名"],i["流派"],i["發(fā)行時(shí)間"],i["評(píng)論數(shù)"],i["歌詞"]])
    for j in i["500條精彩評(píng)論"]:
        writer.writerow([j["評(píng)論內(nèi)容"],j["評(píng)論時(shí)間"],j["評(píng)論點(diǎn)贊次數(shù)"]])
    writer.writerow([])
csv_file.close()
end = time.time()
print("爬取完成,總耗時(shí)"+str(end-start)+"秒")

2.7 代碼注意事項(xiàng)

  • 注意在驅(qū)動(dòng)對(duì)象get請(qǐng)求網(wǎng)頁(yè)之后,要sleep一段時(shí)間,這段時(shí)間是網(wǎng)站用來進(jìn)行ajax請(qǐng)求獲取所需數(shù)據(jù)的,如果不sleep,那么你獲取的數(shù)據(jù)很有可能是空的,或者是默認(rèn)值。

  • 整個(gè)爬下來大概10分鐘的樣子,我已經(jīng)將進(jìn)度輸出,不要提前關(guān)閉,因?yàn)槲沂亲詈蟛艑懭隿sv文件的, 提前關(guān)閉csv文件里什么也沒有。

  • QQ音樂最近有個(gè)bug,就是點(diǎn)擊去獲取更多后,新增的15條評(píng)論還是最初的,可能也是網(wǎng)的原因,代碼那里應(yīng)該沒有問題的。

  • 這個(gè)代碼主要用于爬取主要數(shù)據(jù),很多模擬操作可能不完善。

2.8 使用Padas庫(kù)簡(jiǎn)單的計(jì)算數(shù)據(jù)

  • 有關(guān)Padas庫(kù)的使用,它的兩種數(shù)據(jù)結(jié)構(gòu),請(qǐng)查看官網(wǎng),這里不做說明。

  • 先讀取csv文件中的數(shù)據(jù)到內(nèi)存中,再進(jìn)行操作。

  • 需要先安裝padas庫(kù):


pip install padas


import pandas as pd
import csv
# 這五個(gè)列表用于創(chuàng)建Series
se=[]
names=[]
# 先讀取CSV文件的內(nèi)容至內(nèi)存中
with open("songs.csv",'r',encoding="utf8") as f:
    # 創(chuàng)建閱讀器對(duì)象
    reader = csv.reader(f)
    rows = [row for row in reader]
    index=0
    print("開始解析CSV數(shù)據(jù)...")
    for i in range(5):
        s1=[]
        # 讀取第一行信息
        names.append(rows[index].__str__().split(',')[0][2:-1])
        index+=1
        # 讀取五百條評(píng)論的點(diǎn)贊消息
        for j in range(510):
            s1.append(int(rows[index].__str__().split(',')[2][2:-2]))
            index+=1
        se.append(s1)
        # 讀取掉空行
        index+=1
    print("CSV數(shù)據(jù)解析成功\n")

# 創(chuàng)建的5個(gè)series
for i in range(5):
    series=pd.Series(se[i])
    print("歌曲《"+names[i]+"》的平均點(diǎn)贊次數(shù)是:" + str(series.mean()))
    print("歌曲《" + names[i] + "》的標(biāo)準(zhǔn)差是:" + str(series.std()))
    print()

2.9 大致結(jié)果截圖

image.png

感嘆:爬下幾千條評(píng)論,看了之后,發(fā)現(xiàn),有傷感那味了,哈哈哈

作者:ATFWUS
原文鏈接:https://blog.csdn.net/ATFWUS/article/details/115053245

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 今天感恩節(jié)哎,感謝一直在我身邊的親朋好友。感恩相遇!感恩不離不棄。 中午開了第一次的黨會(huì),身份的轉(zhuǎn)變要...
    余生動(dòng)聽閱讀 10,911評(píng)論 0 11
  • 彩排完,天已黑
    劉凱書法閱讀 4,497評(píng)論 1 3
  • 沒事就多看看書,因?yàn)楦褂性?shī)書氣自華,讀書萬(wàn)卷始通神。沒事就多出去旅游,別因?yàn)闆]錢而找借口,因?yàn)橹灰闶〕詢€用,來...
    向陽(yáng)之心閱讀 4,987評(píng)論 3 11
  • 表情是什么,我認(rèn)為表情就是表現(xiàn)出來的情緒。表情可以傳達(dá)很多信息。高興了當(dāng)然就笑了,難過就哭了。兩者是相互影響密不可...
    Persistenc_6aea閱讀 129,846評(píng)論 2 7

友情鏈接更多精彩內(nèi)容