爬虫笔记三
爬蟲實戰
- 分析網頁
- 找到定制請求頭的信息
- user-agent
- Host
- 愉快的寫代碼了
- 解析網頁
- 獲得`soup對象`
- 排名
- 歌曲名
- 歌手名
- 輸出
- 將數據存到 CSV 文件中
- 爬蟲筆記
分析網頁
首先我們在qq音樂網頁版,找到熱榜界面。
找到定制請求頭的信息
右鍵點擊檢查,找到NetWork并點擊,如果沒有信息,按control +R。
然后就會出現一推文件,一般信息是在第一個。
一般需要兩個信息:user-agent 和 Host
user-agent
Host
一般的都是直接寫出 Host,不過qq音樂就不按常理,不過Host一般是網址的中間部分我們去找尋一下就好了。
愉快的寫代碼了
import requests headers = {'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.107 Safari/537.36 Edg/92.0.902.62','Host':'y.qq.com'} link = 'https://y.qq.com/n/ryqq/toplist/26'r = requests.get(link,headers=headers,timeout=20) #就是響應的對象了,內容就在其中解析網頁
獲得soup對象
soup = BeautifulSoup(r.text,"lxml") #就想到與解析對象排名
我們對比所以的發現所以排名都是這樣的格式,然后分析一下,這里只有
,div 和 class 中只有這一個內容那么我們就選用 BeautifulSoup 的方法
代碼:
def get_rank(soup): #soup 就是上面的 解析對象rank_list = []#找到所有 div(class = 'songlist__number' 元素,返回值是一個列表#我們就在這個列表中找我們需要的就可以了。div_list1 = soup.find_all('div',class_='songlist__number')for each in div_list1:#因為排名直接就在div中了,如果是在<a>中就是each.a.text.strip()rank = each.text.strip()rank_list.append(rank)return rank_list- find_all是找所以結果,如果指向要第一個,就用find就好了。
- strip()的功能是把字符串左右的空格去掉。
歌曲名
我們發現,歌曲名是在<a>元素中,但a的title是歌曲名,這就讓我們很不好通過寫代碼來讀取所以的。所以轉變方法用lxml 的XPath
按我在第二篇筆記中的方法復制下第一首和第二首的XPath來找變化規律。
發現其余都一樣,只有中間的 li [ ]的數字變化,那就好辦了。
def get_music(r): #r 是前邊的響應對象music_list = []#解析為 lxml 格式html = etree.HTML(r.text)for i in range (1,21):#用 xpath 讀取內容#中間的字符通過 for 循環 和 str(i) 來實現,詳細在我第一篇筆記music = html.xpath('//*[@id="app"]/div/div[2]/div[2]/div[3]/ul[2]/li['+str(i)+']/div/div[3]/span/a[2]/text()')music_list.append(music)return music_list注意:
- XPath返回的是一個包含有內容的列表,所以music_list 是一個元素為列表的二維列表
歌手名
我們發現一個如果有多個歌手,在div 中歌手是分布在幾個 <a>中的,那么我們就直接獲取 div 中的內容,這樣返回的就是一個包含多個作者的列表了,
輸出
def show(rank_list,music_list,singer_list,music_time):print()for i in range (20):# 因為 歌曲在上面我已經提到了,是二維列表,所以我么取沒一個行的第一個元素就可以了music = music_list[i][0] print('排名:%s ;歌曲名: %s ;歌手: %s ;時長: %s '%(rank_list[i],music,singer_list[i],music_time[i]))print()將數據存到 CSV 文件中
csv的寫
python自帶了csv模塊提供用戶對csv文件進行讀寫操作,要對csv文件進行寫操作,首先要創建一個writer對象,參考help(csv.writer)。
調用writer對象的前提是:需要傳入一個文件對象,然后才能在這個文件對象的基礎上調用csv的寫入方法writerow(寫入一行)writerows(寫入多行)。寫入數據的代碼如下:
import csvheaders = ['class','name','sex','height','year']rows = [[1,'xiaoming','male',168,23],[1,'xiaohong','female',162,22],[2,'xiaozhang','female',163,21],[2,'xiaoli','male',158,21]]with open('test.csv','w')as f:f_csv = csv.writer(f)f_csv.writerow(headers)f_csv.writerows(rows) #多行的話,需要二維列表代碼:
with open('pa_chong5.csv','a+',encoding = 'UTF-8',newline ='') as csvfile:w = csv.writer(csvfile)music = carry_music(w,music_list) #將歌曲二維變一維# 將所有數據集中到一個二維列表中data = carry_data(rank_list,music,singer_list,music_time)w.writerows(data)效果如下:
詳細代碼可以參考我的博客資源:免費的。
有用的記得點贊,加關注呀
爬蟲筆記
- 爬蟲筆記(1)
- 爬蟲筆記(2)
總結