本文對(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。

- 然后將該路徑配置到環(huán)境變量中:

- 最后到寫段代碼測(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.元素定位方式:

基本上前幾種方式就能夠獲取到需要的元素,需要自己辨別結(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)操作)

- 通過標(biāo)簽對(duì)象調(diào)用即可。
3.鍵盤事件(模擬鍵盤操作)

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)論。



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

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

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

2.4 獲取前五百條評(píng)論消息
我們可以看到熱門評(píng)論一次是十五條,下面有一個(gè)點(diǎn)擊加載更多鏈接,點(diǎn)了之后會(huì)多出15條。
我們需要模擬點(diǎn)擊33次,獲得510條評(píng)論

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é)果截圖

感嘆:爬下幾千條評(píng)論,看了之后,發(fā)現(xiàn),有傷感那味了,哈哈哈
作者:ATFWUS
原文鏈接:https://blog.csdn.net/ATFWUS/article/details/115053245