Python高級應用程序設計任務期末作業


Python高級應用程序設計任務要求

用Python實現一個面向主題的網絡爬蟲程序,並完成以下內容:
(注:每人一題,主題內容自選,所有設計內容與源代碼需提交到博客園平台)

一、主題式網絡爬蟲設計方案(15分)
1.主題式網絡爬蟲名稱

   爬取網易雲音樂歌單

2.主題式網絡爬蟲爬取的內容與數據特征分析

    爬取網易雲音樂歌單前十頁歌單,說唱類型的歌單名稱、歌單播放量、歌單鏈接、用戶名稱。

    分析歌單播放量和歌單標題關鍵詞
3.主題式網絡爬蟲設計方案概述(包括實現思路與技術難點)

實現思路:使用單線程爬取,初始化信息,設置請求頭部信息,獲取網頁資源,使用etree進行網頁解析,爬取多頁時刷新offset,將爬取數據保存到csv文件中。

難點:使用的翻頁形式為URL的limit和offset參數,發送的get請求時froms和url的參數要一至。

二、主題頁面的結構特征分析(15分)
1.主題頁面的結構特

2.Htmls頁面解析

3.節點(標簽)查找方法與遍歷方法
(必要時畫出節點樹結構)

 

 

 

三、網絡爬蟲程序設計(60分)
爬蟲程序主體要包括以下各部分,要附源代碼及較詳細注釋,並在每部分程序后面提供輸出結果的截圖。
1.數據爬取與采集

from urllib import parse
from lxml import etree
from urllib3 import disable_warnings
import requests
import csv
class Wangyiyun(object):

    def __init__(self, **kwargs):
        # 歌單的歌曲風格
        self.types = kwargs['types']
        # 歌單的發布類型
        self.years = kwargs['years']
        # 這是當前爬取的頁數
        self.pages = pages
        # 這是請求的url參數(頁數)
        self.limit = 35
        self.offset = 35 * self.pages - self.limit
        # 這是請求的url
        self.url = "https://music.163.com/discover/playlist/?"


    # 設置請求頭部信息(可擴展:不同的User - Agent)
    def set_header(self):
        self.header = {
            "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.103 Safari/537.36",
            "Referer": "https://music.163.com/",
            "Upgrade-Insecure-Requests": '1',
        }
        return self.header

    # 設置請求表格信息
    def set_froms(self):
        self.key = parse.quote(self.types)
        self.froms = {
            "cat": self.key,
            "order": self.years,
            "limit": self.limit,
            "offset": self.offset,
        }
        return self.froms

    # 解析代碼,獲取有用的數據
    def parsing_codes(self):
        page = etree.HTML(self.code)
        # 標題
        self.title = page.xpath('//div[@class="u-cover u-cover-1"]/a[@title]/@title')
        # 作者
        self.author = page.xpath('//p/a[@class="nm nm-icn f-thide s-fc3"]/text()')
        # 閱讀量
        self.listen = page.xpath('//span[@class="nb"]/text()')
        # 歌單鏈接
        self.link = page.xpath('//div[@class="u-cover u-cover-1"]/a[@href]/@href')
        # 將數據保存為csv文件  
        data=list(zip(self.title,self.author,self.listen,self.link))
        with open('yinyue.csv','a',encoding='utf-8',newline='') as f:
            writer=csv.writer(f)
            #writer.writerow(header)
            writer.writerows(data) 
    # 獲取網頁源代碼
    def get_code(self):
        disable_warnings()
        self.froms['cat']=self.types
        disable_warnings()
        self.new_url = self.url+parse.urlencode(self.froms)
        self.code = requests.get(
            url = self.new_url,
            headers = self.header,
            data = self.froms,
            verify = False,
        ).text

    # 爬取多頁時刷新offset
    def multi(self ,page):
        self.offset = self.limit * page - self.limit


if __name__ == '__main__':
    # 歌單的歌曲風格
    types = "說唱"
    # 歌單的發布類型:最熱=hot,最新=new
    years = "hot"
    # 指定爬取的頁數
    pages = 10
    # 通過pages變量爬取指定頁面
    music = Wangyiyun(
        types = types,
        years = years,
    )
    for i in range(pages):
        page = i+1              # 因為沒有第0頁
        music.multi(page)       # 爬取多頁時指定,傳入當前頁數,刷新offset
        music.set_header()      # 調用頭部方法,構造請求頭信息
        music.set_froms()       # 調用froms方法,構造froms信息
        music.get_code()        # 獲取當前頁面的源碼
        music.parsing_codes()   # 處理源碼,獲取指定數據

2.對數據進行清洗和處理

import pandas as pd
#讀取文件
data=pd.read_csv(r"yinyue.csv",encoding = "utf-8")
data.columns=('title','author','listen_num','link')   
data

 

#刪除沒有萬單位的行
data = data[data["listen_num"].str[-1] == "萬"]
data

 

#刪除萬單位
data['listen_num'] = data['listen_num'].str.strip("萬").apply(int)
data

#刪除重復值
data=data.drop_duplicates()
data.head()

data.describe()

#按播放數量進行降序排序
data = data.sort_values('listen_num',ascending = False).head(10)
data

3.文本分析(可選):jieba分詞、wordcloud可視化
4.數據分析與可視化
(例如:數據柱形圖、直方圖、散點圖、盒圖、分布圖、數據回歸分析等)

import seaborn as sns
import pandas as pd
import matplotlib.pyplot as plt
import matplotlib
#繪制柱狀圖查看top50歌單的播放量分布
plt.hist(data['listen_num'],bins=50)
plt.show()

#繪制直方圖查看播放數量的分布
sns.distplot(data['listen_num'])

 

sns.violinplot(data['listen_num'])

#繪制餅狀圖
plt.rcParams['font.sans-serif'] = ['SimHei']#解決亂碼問題
df_score = data['listen_num'].value_counts() #統計評分情況
plt.title("播放數量占比圖") #設置餅圖標題
plt.pie(df_score.values,labels = df_score.index,autopct='%1.1f%%') #繪圖
#autopct表示圓里面的文本格式,在python里%操作符可用於格式化字符串操作
plt.show()

5.數據持久化

data.to_csv("./wangyiyun.csv")

 

四、結論(10分)
1.經過對主題數據的分析與可視化,可以得到哪些結論?

①數據分析時爬取的數據比較亂,要經過一個連套的數據清洗。

②數據清洗對數據可視化提供了很大的方便。

③top50歌單播放量大部分集中在1000萬左右。

④歌單前十頁的說唱類型播放量在1000萬到2000萬居多。

2.對本次程序設計任務完成的情況做一個簡單的小結。

       在爬取數據過程中,在解析網頁代碼時,返回的是空列表,經過檢查網頁源代碼,發現原來我們所提取的元素包含在<iframe>標簽內部,這樣我們是無法直接定位的,所以必須先切換到iframe中,在爬去過程中小問題很多,到最后爬取到的數據也很“臟”,但是經過數據清洗后,還是可得到一些結論的,經過本次作業中,學習到了必須有耐心和細心,這在往后的碼農生涯將會很受用。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM