一、選題的背景
目前互聯網發達,各種搜索引擎各有千秋,對百度熱搜的分析,可以直觀地看出每個熱點之間的差距,得出熱點關系之間的聯系,以及熱點關鍵詞的關系.
二、主題式網絡爬蟲設計方案
1.主題式網絡爬蟲名稱
《python爬蟲之爬取百度熱搜榜》
2.主題式網絡爬蟲爬取的內容與數據特征分析
爬取內容:"排名","熱搜數據","標題"
數據特征分析:"排名"、"熱度數據"的之間關系整體呈現上升的趨勢,可通過后續繪制直方圖、折線圖等觀察數據的變化情況。
3.主題式網絡爬蟲設計方案概述
實現思路:在瀏覽器 中通過F12訪問網頁源代碼,,分析網站源代碼,找到自己所需要的數據所在的位置,提取數據,對數據進行保存到相同路徑csv文件中,讀取改文件,進行數據清洗,數據模型分析,數據可視化處理,繪制分布圖,用最小二乘法分析兩個變量間的二次擬合方程和繪制擬合曲線。
技術難點:對庫使用和庫中函數的運用,爬取的內容的機構分析處理做數據分析,即求回歸系數,因為標題是文字,無法與數字作比較,需要把標題這一列刪除才可。由於不明原因,輸出結果經常會顯示超出列表范圍。
三.主題頁面的結構特征分析
1.主題頁面的結構與特征分析:先尋找到熱搜對應的網頁代碼,緊接着尋找排名,標題,熱度數據所對應的class標簽。
2.頁面解析
1.
1 #輸入所要爬取的網頁
2 url="https://top.baidu.com/board?tab=realtime"
3 #偽裝爬蟲頭避免被檢測攔截
4 headers = {'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.110 Safari/537.36 Edg/96.0.1054.62'}
5 #請求網站
6 r=requests.get(url) 7 #print(r.text) 8 #對頁面內容重新編碼 9 r.encoding=r.apparent_encoding 10 data=r.text 11 #使用BeautifulSoup 12 soup=BeautifulSoup(data,'html.parser') 13 #顯示網站結構 14 #print(soup.prettify()) 15 head=[] 16 index=[] 17 for i in soup.find_all(class_="hot-index_1Bl1a"): 18 head.append(i.get_text().strip()) 19 for i in soup.find_all(class_="c-single-text-ellipsis"): 20 index.append(i.get_text().strip()) 21 data=[head,index] 22 s=pd.DataFrame(data,index=["標題","熱度數據"]) 23 #將所得數據進行可視化 24 print(s.T)
2.
1 #將數據保存至本地並進行數據的清理
2 S="F:\各種工作雜碎東西\\baidu1.csv"
3 df=pd.DataFrame(data,index=["標題","熱度數據"])
4 df.T.to_csv(S,encoding="utf_8_sig")

1 #清洗數據
2 #有表頭讀入
3 df = pd.read_csv('F:\各種工作雜碎東西\\baidu1.csv')
4 #修改表頭
5 df = pd.read_csv('F:\各種工作雜碎東西\\baidu1.csv',header=None,names=['排名','熱度數據','標題']) 6 #調整排名 7 df=df.drop([0]) 8 for i in range(31): 9 df['排名'].loc[i] =i 10 df
3.
1 #檢查是否有重復值 print(df.duplicated())
4.
1 #檢查是否有空值 2 print(df['熱度數據'].isnull().value_counts())
5.
1 #異常值處理 2 print(df.describe())
6.
1 from sklearn.linear_model import LinearRegression
2 X = df.drop("標題",axis=1) 3 predict_model = LinearRegression() 4 predict_model.fit(X,df['熱度數據']) 5 print("回歸系數為:",predict_model.coef_)
7.
1 #繪制排名與熱度的回歸圖
2 import seaborn as sns
3 sns.lmplot(x='排名', y='熱度數據', data=df, ci=None)
8.
1 import numpy as np
2 #畫出散點圖
3 plt.rcParams['font.sans-serif'] = ['SimHei'] # 用來正常顯示中文標簽
4 plt.rcParams['axes.unicode_minus'] = False # 用來正常顯示負號
5 N=100
6 x=np.random.rand(N) 7 y=np.random.rand(N) 8 size=50 9 plt.xlabel("排名") 10 plt.ylabel("熱度數據") 11 plt.scatter(x,y,size,color='b',alpha=0.5,marker="o") 12 #散點圖 13 sns.jointplot(x="排名",y="熱度數據",data=df,kind='reg',color='g') 14 sns.jointplot(x="排名",y="熱度數據",data=df,kind='hex',color='r') 15 sns.jointplot(x="排名",y="熱度數據",data=df,kind="kde",space=0,color='bule')
9.
1 import csv
2 import matplotlib.pyplot as plt 3 import pandas as pd 4 xdata = [] 5 ydata = [] 6 xdata = df.loc[:,'排名'] #將csv中列名為“列名1”的列存入xdata數組中 7 #如果ix報錯請將其改為loc 8 ydata = df.loc[:,'熱度數據'] 9 plt.plot(xdata,ydata,'bo-',label=u'',linewidth=1) 10 plt.title(u"折線圖",size=10) #設置表名為“表名” 11 plt.legend() 12 plt.xlabel(u'排名',size=10) #設置x軸名為“x軸名” 13 plt.ylabel(u'熱度數據',size=10) #設置y軸名為“y軸名” 14 plt.show()
10.
1 #標題直方圖分析趨勢
2 import matplotlib.pyplot as plt
3 x = df['標題'].head(20) 4 y = df['熱度數據'].head(20) 5 plt.rcParams['font.sans-serif']=['SimHei'] #用來正常顯示中文標簽 6 plt.rcParams['axes.unicode_minus']=False 7 plt.xticks(rotation=90) 8 plt.bar(x,y,alpha=0.2, width=0.4, color='b', lw=3,label="標題") 9 plt.plot(x,y,'-',color = 'r',label="熱度數據") 10 plt.legend(loc = "best")#圖例 11 plt.title("熱搜指數趨勢圖") 12 plt.xlabel("標題",)#橫坐標名字 13 plt.ylabel("熱度數據")#縱坐標名字 14 plt.show()
11.
1 #標題水平直方圖
2 plt.barh(x,y, alpha=0.2, height=0.4, color='red',label="熱度數據", lw=3)
3 plt.title("熱搜指數水平圖") 4 plt.legend(loc = "best")#圖例 5 plt.xlabel("標題",)#橫坐標名字 6 plt.ylabel("熱度數據")#縱坐標名字 7 plt.show()
12.
1 #繪畫盒圖
2 plt.xlabel("排名")
3 plt.ylabel("熱度數據") 4 sns.boxplot(x='排名',y='熱度數據',data=df)
13.
1 #標題雲圖
2 import pandas as pd
3 import numpy as np 4 import wordcloud as wc 5 from PIL import Image 6 import matplotlib.pyplot as plt 7 import random 8 9 bk = np.array(Image.open(r"C:\Users\12278\Desktop\無標題.png")) 10 mask = bk 11 # 定義尺寸 12 word_cloud = wc.WordCloud( 13 width=2000, # 詞雲圖寬 14 height=1000, # 詞雲圖高 15 mask = mask, 16 background_color='black', # 詞雲圖背景顏色,默認為白色 17 font_path='msyhbd.ttc', # 詞雲圖 字體(中文需要設定為本機有的中文字體) 18 max_font_size=400, # 最大字體,默認為200 19 random_state=50, # 為每個單詞返回一個PIL顏色 20 ) 21 text = df["標題"] 22 text = " ".join(text) 23 word_cloud.generate(text) 24 plt.imshow(word_cloud) 25 plt.show()
1 #數據持久化
2 df = pd.DataFrame(df,columns=["排名","熱度數據","標題"])
3 df.to_csv('百度3.csv',encoding = 'gbk') #保存文件,數據持久化
四.完整代碼
1 #輸入所要爬取的網頁
2 url="https://top.baidu.com/board?tab=realtime"
3 #偽裝爬蟲頭避免被檢測攔截
4 headers = {'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.110 Safari/537.36 Edg/96.0.1054.62'}
5 #請求網站
6 r=requests.get(url) 7 #print(r.text) 8 #對頁面內容重新編碼 9 r.encoding=r.apparent_encoding 10 data=r.text 11 #使用BeautifulSoup 12 soup=BeautifulSoup(data,'html.parser') 13 #顯示網站結構 14 #print(soup.prettify()) 15 head=[] 16 index=[] 17 for i in soup.find_all(class_="hot-index_1Bl1a"): 18 head.append(i.get_text().strip()) 19 for i in soup.find_all(class_="c-single-text-ellipsis"): 20 index.append(i.get_text().strip()) 21 data=[head,index] 22 s=pd.DataFrame(data,index=["標題","熱度數據"]) 23 #將所得數據進行可視化 24 print(s.T) 25 #將數據保存至本地並進行數據的清理 26 S="F:\各種工作雜碎東西\\baidu1.csv" 27 df=pd.DataFrame(data,index=["標題","熱度數據"]) 28 df.T.to_csv(S,encoding="utf_8_sig") 29 30 #清洗數據 31 #有表頭讀入 32 df = pd.read_csv('F:\各種工作雜碎東西\\baidu1.csv') 33 #修改表頭 34 df = pd.read_csv('F:\各種工作雜碎東西\\baidu1.csv',header=None,names=['排名','熱度數據','標題']) 35 #調整排名 36 df=df.drop([0]) 37 for i in range(31): 38 df['排名'].loc[i] =i 39 #清洗數據 40 #有表頭讀入 41 df = pd.read_csv('F:\各種工作雜碎東西\\baidu1.csv') 42 #修改表頭 43 df = pd.read_csv('F:\各種工作雜碎東西\\baidu1.csv',header=None,names=['排名','熱度數據','標題']) 44 #調整排名 45 df=df.drop([0]) 46 for i in range(31): 47 df['排名'].loc[i] =i 48 #清洗數據 49 #有表頭讀入 50 df = pd.read_csv('F:\各種工作雜碎東西\\baidu1.csv') 51 #修改表頭 52 df = pd.read_csv('F:\各種工作雜碎東西\\baidu1.csv',header=None,names=['排名','熱度數據','標題']) 53 #調整排名 54 df=df.drop([0]) 55 for i in range(31): 56 df['排名'].loc[i] =i 57 #檢查是否有重復值 58 print(df.duplicated()) 59 #檢查是否有空值 60 print(df['熱度數據'].isnull().value_counts()) 61 #異常值處理 62 print(df.describe()) 63 X = df.drop("標題",axis=1) 64 predict_model = LinearRegression() 65 predict_model.fit(X,df['熱度數據']) 66 print("回歸系數為:",predict_model.coef_) 67 sns.lmplot(x='排名', y='熱度數據', data=df, ci=None) 68 #畫出散點圖 69 plt.rcParams['font.sans-serif'] = ['SimHei'] # 用來正常顯示中文標簽 70 plt.rcParams['axes.unicode_minus'] = False # 用來正常顯示負號 71 N=100 72 x=np.random.rand(N) 73 y=np.random.rand(N) 74 size=50 75 plt.xlabel("排名") 76 plt.ylabel("熱度數據") 77 plt.scatter(x,y,size,color='b',alpha=0.5,marker="o") 78 #散點圖 79 sns.jointplot(x="排名",y="熱度數據",data=df,kind='reg',color='g') 80 sns.jointplot(x="排名",y="熱度數據",data=df,kind='hex',color='r') 81 sns.jointplot(x="排名",y="熱度數據",data=df,kind="kde",space=0,color='bule') 82 xdata = [] 83 ydata = [] 84 xdata = df.loc[:,'排名'] #將csv中列名為“列名1”的列存入xdata數組中 85 #如果ix報錯請將其改為loc 86 ydata = df.loc[:,'熱度數據'] 87 plt.plot(xdata,ydata,'bo-',label=u'',linewidth=1) 88 plt.title(u"折線圖",size=10) #設置表名為“表名” 89 plt.legend() 90 plt.xlabel(u'排名',size=10) #設置x軸名為“x軸名” 91 plt.ylabel(u'熱度數據',size=10) #設置y軸名為“y軸名” 92 plt.show() 93 x = df['標題'].head(20) 94 y = df['熱度數據'].head(20) 95 plt.rcParams['font.sans-serif']=['SimHei'] #用來正常顯示中文標簽 96 plt.rcParams['axes.unicode_minus']=False 97 plt.xticks(rotation=90) 98 plt.bar(x,y,alpha=0.2, width=0.4, color='b', lw=3,label="標題") 99 plt.plot(x,y,'-',color = 'r',label="熱度數據") 100 plt.legend(loc = "best")#圖例 101 plt.title("熱搜指數趨勢圖") 102 plt.xlabel("標題",)#橫坐標名字 103 plt.ylabel("熱度數據")#縱坐標名字 104 plt.show() 105 #標題水平直方圖 106 plt.barh(x,y, alpha=0.2, height=0.4, color='red',label="熱度數據", lw=3) 107 plt.title("熱搜指數水平圖") 108 plt.legend(loc = "best")#圖例 109 plt.xlabel("標題",)#橫坐標名字 110 plt.ylabel("熱度數據")#縱坐標名字 111 plt.show() 112 #標題散點圖 113 114 plt.scatter(x,y,color='b',marker='o',s=40,alpha=0.5) 115 plt.xticks(rotation=90) 116 plt.title("熱搜指數散點圖") 117 plt.xlabel("hot_title",)#橫坐標名字 118 plt.ylabel("hot_zhishu")#縱坐標名字 119 plt.show() 120 bk = np.array(Image.open(r"C:\Users\12278\Desktop\無標題.png")) 121 mask = bk 122 # 定義尺寸 123 word_cloud = wc.WordCloud( 124 width=2000, # 詞雲圖寬 125 height=1000, # 詞雲圖高 126 mask = mask, 127 background_color='black', # 詞雲圖背景顏色,默認為白色 128 font_path='msyhbd.ttc', # 詞雲圖 字體(中文需要設定為本機有的中文字體) 129 max_font_size=400, # 最大字體,默認為200 130 random_state=50, # 為每個單詞返回一個PIL顏色 131 ) 132 text = df["標題"] 133 text = " ".join(text) 134 word_cloud.generate(text) 135 plt.imshow(word_cloud) 136 plt.show() 137 #繪畫盒圖 138 plt.xlabel("排名") 139 plt.ylabel("熱度數據") 140 sns.boxplot(x='排名',y='熱度數據',data=df) 141 #數據持久化 142 df = pd.DataFrame(df,columns=["排名","熱度數據","標題"]) 143 df.to_csv('百度3.csv',encoding = 'gbk') #保存文件,數據持久化
四.總結
1.通過對數據的分析可以發現整體的熱度是成一次函數形式上升的,並且熱度值最高點與最低點之間相差300W之間,普通熱點第一一般不會超過500W,最低熱點也有200W以上。
2.小結:在這次對百度熱榜的分析的過程中,我從中學會了不少函數及用法。很多次都卡在一個點上,絞盡腦汁去想解決問題的辦法,通過觀看b站的視頻,百度搜索等方法去找尋答案。這兩個星期來也養成了耐心和獨立思考的習慣,並且提高了我對Python的興趣。