本文對使用到的技術(shù)僅做簡單的介紹魏身,若想了解更多肛炮,請前往相應的官網(wǎng)網(wǎng)站進行學習止吐。 本文適合對爬蟲相關(guān)知識接觸不多的新手宝踪,主要是普及Selenium如何做爬蟲,大佬請?zhí)^碍扔。
01 Selenium簡單介紹
1.1.簡介
Selenium是一個用于測試網(wǎng)站的自動化測試工具瘩燥,支持各種主流界面瀏覽器。
簡而言之不同,Selenium是一個用來做網(wǎng)站自動化測試的庫厉膀,它的定位是做自動化測試的。我們也可以利用它來做爬蟲二拐,獲取一些網(wǎng)頁信息服鹅,并且這種爬蟲是模擬真實瀏覽器操作的,實用性更強百新。
Selenium是市面上唯一一款可以與付費產(chǎn)品競爭的自動化測試工具企软。
如果想了解更多,可以前往Selenium中文網(wǎng)學習
1.2.安裝
- 要使用Selenium首先要在python中安裝相關(guān)的庫:
pip install Selenium
安裝相應瀏覽器的webdricer驅(qū)動文件饭望,這里提供chrome的鏈接仗哨,其它瀏覽器網(wǎng)上搜一搜就有。選擇合適的版本铅辞,我選擇的是2.23厌漂。
下載解壓后得到exe文件,將這個文件拷貝到chrom的安裝文件夾下:
一般是C:\Program Files (x86)\Google\Chrome\Application斟珊,或者是C:\Program Files\Google\Chrome\Application苇倡。
- 然后將該路徑配置到環(huán)境變量中:
- 最后到寫段代碼測試一下:
from selenium import webdriver
driver=webdriver.Chrome(executable_path="C:\Program Files (x86)\Google\Chrome\Application\chromedriver.exe")
如果看到開啟了一個瀏覽器窗口就是成功了,否則下面會有相應的報錯信息倍宾,需要檢查前面的步驟雏节。
1.3.簡單使用介紹
1.元素定位方式:
基本上前幾種方式就能夠獲取到需要的元素,需要自己辨別結(jié)果是否唯一來選擇相應的選擇器高职。
通過drive對象調(diào)用此方法钩乍,返回的是標簽對象,或者是標簽對象的列表怔锌,可以通過.text獲取該標簽下的文字寥粹,可以通過get_attribute()獲取標簽的其它屬性值。
分享快速定位元素的小妙招:看所需信息所在的標簽的id埃元,class涝涤,name的名稱是否與標簽下信息的語義有關(guān),一般有關(guān)的都代表是唯一的岛杀。(從開發(fā)者的角度去思考)若無法通過當前標簽唯一定位阔拳,則考慮父級標簽,一次類推类嗤,總是能找到定位的方法的糊肠。
2.鼠標事件(模擬鼠標操作)
- 通過標簽對象調(diào)用即可辨宠。
3.鍵盤事件(模擬鍵盤操作)
4.其他操作
- 其他操作包括控制瀏覽器的操作,獲取斷言信息货裹,表單切換嗤形,多窗口切換,警告框處理弧圆,下拉框處理赋兵,文件上傳操作,cookie操作搔预,調(diào)用js代碼霹期,截圖,關(guān)閉瀏覽器等操作斯撮,因為在這里用的不多经伙,就沒有一一羅列,自行去官網(wǎng)學習勿锅。
02 爬取目標
這個實戰(zhàn)爬蟲主要完成以下目標:
爬取QQ音樂官網(wǎng)指定歌手的前5首歌曲的基本信息和前五百條熱門評論帕膜。
2.1 獲取前五歌曲的url
- 分析該頁面的代碼得知,包裹所有歌曲信息的標簽的class是唯一的溢十,我們可以獲取到它垮刹,再遍歷所有子標簽,也可以一次得到所有包裹歌曲信息的div张弛,再獲取里面的a標簽荒典。
2.2 獲取歌曲基本信息
- 可以看到基本信息標簽里的class名稱是有一部分帶語義的,那么通過css選擇器肯定可以唯一確定下來吞鸭。
2.3 獲取歌詞
- 頁面上的歌詞不完整寺董,似乎需要點擊展開才行,但其實所有歌詞已經(jīng)在標簽里面了刻剥,只是顯示的問題了遮咖。
2.4 獲取前五百條評論消息
我們可以看到熱門評論一次是十五條,下面有一個點擊加載更多鏈接造虏,點了之后會多出15條御吞。
我們需要模擬點擊33次,獲得510條評論
2.5 寫入CSV文件
使用csv庫漓藕,將爬取到的數(shù)據(jù)寫入到csv文件中進行持久化陶珠。
2.6 實現(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
# 爬取周杰倫最熱門五首歌曲的基本信息,歌詞享钞,前五百條熱門評論
# 此代碼僅供交流學習使用
#
#1.創(chuàng)建Chrome瀏覽器對象揍诽,這會在電腦上在打開一個瀏覽器窗口
driver=webdriver.Chrome(executable_path="C:\Program Files (x86)\Google\Chrome\Application\chromedriver.exe")
#2.打開QQ音樂 -周杰倫頁面
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)
# 這個0.5秒用于等待異步請求的完成
sleep(0.8)
# 獲取歌曲名
song_name=driver.find_element_by_class_name("data__name_txt").text
print("開始獲取歌曲《"+song_name+"》的基本信息")
# 獲取流派,發(fā)行時間,評論數(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 + "》的歌詞")
# 點擊展開歌詞
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條熱門評論")
# 獲取500條評論
comments=[]
# 點擊加載更多29次寝姿,每次多出15條評論
for i in range(33):
driver.find_element_by_partial_link_text("點擊加載更多").click()
print("開始獲取歌曲《" + song_name + "》的第"+str((i+1)*15+1)+"-"+str((i+2)*15)+"條熱門評論")
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({"評論內(nèi)容":content})
comment.update({"評論時間":content_time})
comment.update({"評論點贊次數(shù)":zan_num})
comments.append(comment)
print("歌曲《" + song_name + "》的前五百條熱門評論獲取完畢")
print("歌曲《"+song_name+"》所有信息獲取完畢")
print()
song_resourse.update({"歌曲名":song_name})
song_resourse.update({"流派":song_liupai})
song_resourse.update({"發(fā)行時間":song_time})
song_resourse.update({"評論數(shù)":song_comment_num})
song_resourse.update({"歌詞":lyic})
song_resourse.update({"500條精彩評論":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ā)行時間"],i["評論數(shù)"],i["歌詞"]])
for j in i["500條精彩評論"]:
writer.writerow([j["評論內(nèi)容"],j["評論時間"],j["評論點贊次數(shù)"]])
writer.writerow([])
csv_file.close()
end = time.time()
print("爬取完成交排,總耗時"+str(end-start)+"秒")
2.7 代碼注意事項
注意在驅(qū)動對象get請求網(wǎng)頁之后,要sleep一段時間饵筑,這段時間是網(wǎng)站用來進行ajax請求獲取所需數(shù)據(jù)的,如果不sleep处坪,那么你獲取的數(shù)據(jù)很有可能是空的根资,或者是默認值。
整個爬下來大概10分鐘的樣子同窘,我已經(jīng)將進度輸出玄帕,不要提前關(guān)閉,因為我是最后才寫入csv文件的想邦, 提前關(guān)閉csv文件里什么也沒有裤纹。
QQ音樂最近有個bug,就是點擊去獲取更多后丧没,新增的15條評論還是最初的鹰椒,可能也是網(wǎng)的原因,代碼那里應該沒有問題的呕童。
這個代碼主要用于爬取主要數(shù)據(jù)漆际,很多模擬操作可能不完善。
2.8 使用Padas庫簡單的計算數(shù)據(jù)
有關(guān)Padas庫的使用夺饲,它的兩種數(shù)據(jù)結(jié)構(gòu)奸汇,請查看官網(wǎng),這里不做說明往声。
先讀取csv文件中的數(shù)據(jù)到內(nèi)存中擂找,再進行操作。
需要先安裝padas庫:
pip install padas
import pandas as pd
import csv
# 這五個列表用于創(chuàng)建Series
se=[]
names=[]
# 先讀取CSV文件的內(nèi)容至內(nèi)存中
with open("songs.csv",'r',encoding="utf8") as f:
# 創(chuàng)建閱讀器對象
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
# 讀取五百條評論的點贊消息
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個series
for i in range(5):
series=pd.Series(se[i])
print("歌曲《"+names[i]+"》的平均點贊次數(shù)是:" + str(series.mean()))
print("歌曲《" + names[i] + "》的標準差是:" + str(series.std()))
print()
2.9 大致結(jié)果截圖
感嘆:爬下幾千條評論浩销,看了之后贯涎,發(fā)現(xiàn),有傷感那味了撼嗓,哈哈哈
作者:ATFWUS
原文鏈接:https://blog.csdn.net/ATFWUS/article/details/115053245