用 Python 實現一個面向主題的網絡爬蟲程序,並完成以下內容:
【要求:】
●每人一題,主題內容自選,所有設計內容與源代碼需提交到博客園平台。
●課程設計要求獨立完成,可以參考網絡資源,但不能全盤抄襲,整個設計代碼
應有一定的規模(
300 行左右)。
●課程設計占總成績的 60%。
一、選題的背景
為什么要選擇此選題?要達到的數據分析的預期目標是什么?(10 分)從社會、經濟、技術、數據來源等方面進行描述(200 字以內)
隨着時代的進步,微博已成為人們獲取重大消息的主要途徑之一。所以我想對微博熱搜榜前40進行數據爬取,然后進行可視化分析。數據分析的目標是通過python中的matplotlib、pandas、seaborn、wordcloud、jieba等庫做出圖表和雲詞圖讓我們能快速精確地知道發生了什么重大事件和了解每天的熱搜信息。
二、主題式網絡爬蟲設計方案(
10 分)
1.主題式網絡爬蟲名稱
對微博熱搜的爬取及數據分析
2.主題式網絡爬蟲爬取的內容與數據特征分析
爬蟲爬取的內容:爬取微博熱搜的數據; 數據特征分析:各數據分布緊密聯系
3.主題式網絡爬蟲設計方案概述(包括實現思路與技術難點)
實現思路:通過訪問網頁源代碼使用xpath正則表達爬取數據,對數據進行保存數據,再對數據進行清洗和處理,數據分析與可視化處理。
技術難點:在編程的過程中,若中間部分出現錯誤,可能導致整個代碼需要重新修改。數據實時更新,會導致部分上傳的圖形不一致。
三、主題頁面的結構特征分析(10 分)
1.主題頁面的結構與特征分析
通過觀察頁面HTML源代碼,可以發現爬取數據都分布在標簽'div.cc-cd-cb nano has-scrollbar'里面,標題標簽為'span.t',熱度標簽為'span.e'。
2.Htmls 頁面解析
我爬取的網站是
https://tophub.today/
具體為先確定爬取的是2021年12月22日微博的熱搜排名、今日熱搜和熱度
通過F12,對頁面進行檢查,查看我們所需要爬取內容的相關代碼

四、網絡爬蟲程序設計(60 分)
爬蟲程序主體要包括以下各部分,要附源代碼及較詳細注釋,並在每部分程序后
面提供輸出結果的截圖。
1.數據爬取與采集
通過運用python中的requests、lxml、pandas庫對網頁進行爬取數據,然后將數據存為csv文件。
import requests from lxml import etree import pandas as pd import numpy as np import matplotlib.pyplot as plt import matplotlib from scipy.optimize import leastsq import scipy.stats as sts import seaborn as sns url = "https://tophub.today/" headers = {'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.102 Safari/537.36 Edge/18.18362'} html = requests.get(url,headers = headers) html = html.content.decode('utf-8') html = etree.HTML(html) div = html.xpath("//div[@id='node-1']/div") for a in div: titles = a.xpath(".//span[@class='t']/text()") numbers = a.xpath(".//span[@class='e']/text()") b = [] for i in range(40): b.append([i+1,titles[i],numbers[i][:-1]]) file = pd.DataFrame(b,columns = ['排名','今日熱搜','熱度(單位為萬)']) print(file) file.to_csv('微博熱搜榜熱度數據.csv')
2.對數據進行清洗和處理
import pandas as pd import numpy as np import matplotlib.pyplot as plt #讀取csv文件 s=pd.read_csv("微博熱搜榜熱度數據.csv") s
進行重復值處理,檢查是否有重復值
s.duplicated() #檢查是否有重復值
從以上得知該數據沒有重復值。
接下去對數據進行查看統計信息
#使用describe查看統計信息 s.describe()
s.info() #查看各列數據類型
4.數據分析與可視化(例如:數據柱形圖、直方圖、散點圖、盒圖、分布圖)
#繪制折線圖
import pandas as pd import numpy as np import matplotlib.pyplot as plt data=pd.read_csv("微博熱搜榜熱度數據.csv") s=(data.head(20)) plt.rcParams['font.sans-serif'] = 'simhei' plt.rcParams['axes.unicode_minus']=False s = np.array(s) plt.plot(s[:,1],s[:,3],'-*') plt.xlabel("排行榜") plt.title(u'微博熱搜榜熱度數據') plt.show()
#繪制柱形圖
import pandas as pd import numpy as np import matplotlib.pyplot as plt data=pd.read_csv("微博熱搜榜熱度數據.csv") s=(data.head(10)) plt.rcParams['font.sans-serif']=['SimHei'] plt.rcParams['axes.unicode_minus'] = False fig = plt.figure() plt.bar(s['排名'], s['熱度(單位為萬)']) plt.title(u'微博熱搜榜熱度數據') plt.xlabel('排名', size=10) plt.ylabel(u'熱度(單位為萬)') plt.show()
#繪制餅圖
import pandas as pd import numpy as np import matplotlib.pyplot as plt data=pd.read_csv("微博熱搜榜熱度數據.csv") s=(data.head(15)) plt.rcParams['font.sans-serif'] = ['SimHei'] #解決亂碼問題 df_score = s['熱度(單位為萬)'].value_counts() #統計評分情況 plt.title("微博熱搜榜熱度數據分布情況") #設置餅圖標題 plt.pie(df_score.values,labels = df_score.index,autopct='%1.1f%%') #繪圖 #autopct表示圓里面的文本格式,在python里%操作符可用於格式化字符串操作 plt.show()
5.根據數據之間的關系,分析兩個變量之間的相關系數,畫出散點圖,並建立變
量之間的回歸方程(一元或多元)。
#線性回歸圖
import pandas as pd import numpy as np import matplotlib.pyplot as plt import seaborn as sns df=pd.read_csv("微博熱搜榜熱度數據.csv") sns.lmplot(x='排名',y='熱度(單位為萬)',data=df) plt.show()
#排名與熱度散點圖
import pandas as pd import numpy as np import matplotlib.pyplot as plt import seaborn as sns df=pd.read_csv("微博熱搜榜熱度數據.csv") x = df['排名'] y = df['熱度(單位為萬)'] plt.xlabel('排名') plt.ylabel('熱度(單位為萬)') plt.scatter(x,y,color="red",label=u"熱度分布數據",linewidth=2) plt.title("繪制排名與熱度散點圖") plt.legend() plt.show()
由於csv文件不能直接讀取,所以將csv文件轉為txt文件。
import pandas as pd data = pd.read_csv("微博熱搜榜熱度數據.csv") s=data.iloc[:,1:4] s.to_csv('微博熱搜榜熱度數據.txt',index=False,sep=' ',encoding='utf_8_sig')
#繪制詞雲
import jieba from matplotlib import pyplot as plt from wordcloud import WordCloud from PIL import Image import numpy as np #r''單引號里面不需要轉義 from os import path #繪制圖片 from wordcloud import WordCloud,ImageColorGenerator import jieba import matplotlib.pyplot as plt import matplotlib.image as mpimg import numpy as np img = mpimg.imread('微博.jpg') print (img.shape) plt.imshow(img) font = r'C:\Windows\Fonts\FZSTK.TTF' #電腦自帶的字體 def tcg(texts): cut = jieba.cut(texts) #分詞 string = ' '.join(cut) return string text = (open('微博熱搜榜熱度數據.txt','r',encoding='utf-8')).read() string=tcg(text) img_array = np.array(img) #將圖片裝換為數組 stopword=[''] #設置停止詞,也就是你不想顯示的詞 wc = WordCloud( background_color='white', width=1000, height=800, mask=img_array, #設置背景圖片 font_path=font, stopwords=stopword ) wc.generate_from_text(string)#繪制圖片 plt.imshow(wc) plt.axis('off') plt.show() wc.to_file('微博熱搜榜熱度數據.jpg')
7.將以上各部分的代碼匯總,附上完整程序代碼
1 #導入庫 2 3 import requests 4 from lxml import etree 5 import pandas as pd 6 import numpy as np 7 import matplotlib.pyplot as plt 8 import matplotlib 9 from scipy.optimize import leastsq 10 import scipy.stats as sts 11 import seaborn as sns 12 13 url = "https://tophub.today/" 14 headers = {'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.102 Safari/537.36 Edge/18.18362'} 15 html = requests.get(url,headers = headers) 16 17 html = html.content.decode('utf-8') 18 html = etree.HTML(html) 19 20 div = html.xpath("//div[@id='node-1']/div") 21 for a in div: 22 titles = a.xpath(".//span[@class='t']/text()") 23 numbers = a.xpath(".//span[@class='e']/text()") 24 25 b = [] 26 for i in range(40): 27 b.append([i+1,titles[i],numbers[i][:-1]]) 28 file = pd.DataFrame(b,columns = ['排名','今日熱搜','熱度(單位為萬)']) 29 print(file) 30 file.to_csv('微博熱搜榜熱度數據.csv') 31 32 #爬取數據,然后將數據存為csv文件 33 34 35 import pandas as pd 36 import numpy as np 37 import matplotlib.pyplot as plt 38 #讀取csv文件 39 s=pd.read_csv("微博熱搜榜熱度數據.csv") 40 s 41 42 43 s.duplicated() 44 45 #檢查是否有重復值 46 47 48 #使用describe查看統計信息 49 50 s.describe() 51 52 53 s.info() 54 55 #查看各列數據類型 56 57 58 #繪制折線圖 59 60 import pandas as pd 61 import numpy as np 62 import matplotlib.pyplot as plt 63 data=pd.read_csv("微博熱搜榜熱度數據.csv") 64 s=(data.head(20)) 65 plt.rcParams['font.sans-serif'] = 'simhei' 66 plt.rcParams['axes.unicode_minus']=False 67 s = np.array(s) 68 plt.plot(s[:,1],s[:,3],'-*') 69 plt.xlabel("排行榜") 70 plt.title(u'微博熱搜榜熱度數據') 71 plt.show() 72 73 74 #繪制柱形圖 75 76 import pandas as pd 77 import numpy as np 78 import matplotlib.pyplot as plt 79 data=pd.read_csv("微博熱搜榜熱度數據.csv") 80 s=(data.head(10)) 81 plt.rcParams['font.sans-serif']=['SimHei'] 82 plt.rcParams['axes.unicode_minus'] = False 83 fig = plt.figure() 84 plt.bar(s['排名'], s['熱度(單位為萬)']) 85 plt.title(u'微博熱搜榜熱度數據') 86 plt.xlabel('排名', size=10) 87 plt.ylabel(u'熱度(單位為萬)') 88 plt.show() 89 90 91 #繪制餅圖 92 93 import pandas as pd 94 import numpy as np 95 import matplotlib.pyplot as plt 96 data=pd.read_csv("微博熱搜榜熱度數據.csv") 97 s=(data.head(15)) 98 plt.rcParams['font.sans-serif'] = ['SimHei'] 99 #解決亂碼問題 100 101 df_score = s['熱度(單位為萬)'].value_counts() 102 #統計評分情況 103 104 plt.title("微博熱搜榜熱度數據分布情況") 105 #設置餅圖標題 106 107 plt.pie(df_score.values,labels = df_score.index,autopct='%1.1f%%') 108 #繪圖 109 #autopct表示圓里面的文本格式,在python里%操作符可用於格式化字符串操作 110 111 plt.show() 112 113 114 #繪制線性回歸圖 115 116 import pandas as pd 117 import numpy as np 118 import matplotlib.pyplot as plt 119 import seaborn as sns 120 df=pd.read_csv("微博熱搜榜熱度數據.csv") 121 sns.lmplot(x='排名',y='熱度(單位為萬)',data=df) 122 plt.show() 123 124 125 #繪制排名與熱度散點圖 126 import pandas as pd 127 import numpy as np 128 import matplotlib.pyplot as plt 129 import seaborn as sns 130 df=pd.read_csv("微博熱搜榜熱度數據.csv") 131 x = df['排名'] 132 y = df['熱度(單位為萬)'] 133 plt.xlabel('排名') 134 plt.ylabel('熱度(單位為萬)') 135 plt.scatter(x,y,color="red",label=u"熱度分布數據",linewidth=2) 136 plt.title("繪制排名與熱度散點圖") 137 plt.legend() 138 plt.show() 139 140 141 #將csv文件轉為txt文件 142 import pandas as pd 143 data = pd.read_csv("微博熱搜榜熱度數據.csv") 144 s=data.iloc[:,1:4] 145 s.to_csv('微博熱搜榜熱度數據.txt',index=False,sep=' ',encoding='utf_8_sig') 146 147 148 #繪制詞雲 149 import jieba 150 from matplotlib import pyplot as plt 151 from wordcloud import WordCloud 152 from PIL import Image 153 import numpy as np 154 #r''單引號里面不需要轉義 155 from os import path 156 #繪制圖片 157 from wordcloud import WordCloud,ImageColorGenerator 158 import jieba 159 import matplotlib.pyplot as plt 160 import matplotlib.image as mpimg 161 import numpy as np 162 img = mpimg.imread('微博.jpg') 163 print (img.shape) 164 plt.imshow(img) 165 font = r'C:\Windows\Fonts\FZSTK.TTF' 166 #電腦自帶的字體 167 def tcg(texts): 168 cut = jieba.cut(texts) 169 #分詞 170 string = ' '.join(cut) 171 return string 172 text = (open('微博熱搜榜熱度數據.txt','r',encoding='utf-8')).read() 173 string=tcg(text) 174 img_array = np.array(img) 175 #將圖片裝換為數組 176 stopword=[''] 177 #設置停止詞,也就是你不想顯示的詞 178 wc = WordCloud( 179 background_color='white', 180 width=1000, 181 height=800, 182 mask=img_array, 183 #設置背景圖片 184 font_path=font, 185 stopwords=stopword 186 ) 187 wc.generate_from_text(string)#繪制圖片 188 plt.imshow(wc) 189 plt.axis('off') 190 plt.show() 191 wc.to_file('微博熱搜榜熱度數據.jpg')
五、總結(10 分)
1.經過對主題數據的分析與可視化,可以得到哪些結論?是否達到預期的目標?
結論:1、top40的微博熱度集中在100萬左右。2、微博熱點前十名的熱點在100萬到1000萬居多。
已達到預期的目標,通過爬蟲技術對爬取到的微博熱搜的熱度等有了了解,發現娛樂類新聞更容易上熱搜。
2.在完成此設計過程中,得到哪些收獲?以及要改進的建議?
收獲:能夠更好地用爬蟲技術對網頁進行爬取等
建議:對python庫的應用還不夠嫻熟,在編程過程中,中間部分若出錯則可能需要整個代碼重新修改。要加強python的學習。