一、選題背景
通過爬取起點中文網熱門小說信息,可以時實的了解到現在,熱門小說的寫作方向、主題等,也可以大致了解讀者對小說的消費情況。
二、主題式網絡爬蟲設計方案
1.主題式網絡爬蟲名稱
起點中文網熱門小說信息爬取
2.主題式網絡爬蟲爬取的內容與數據特征分析
爬取起點中文網
https://www.qidian.com/ 熱門小說信息(小說名稱,推薦數量),在分析小說的多個特征值時,本文提取了推薦數量這一值作為比較
3.主題式網絡爬蟲設計方案概述(包括實現思路與技術難點)
訪問網頁得到狀態碼200,分析網頁源代碼,找出所需要的的標簽,逐個提取標簽保存到相同路徑excel
文件中,讀取改文件,進行數據清洗,數據可視化處理,用最小二乘法分析兩個變量間的二次擬合方程和繪制擬合曲線。
三、主題頁面的結構特征分析
1.主題頁面的結構與特征分析:可以發現我們需要的內容在'li'路徑里面,同時我發現第一本書對於其他書差距太過巨大,就不對其進行分析,只分析后面的書籍。
2.頁面解析:
三、
1.
1 from bs4 import BeautifulSoup 2 import requests 3 import pandas as pd 4 import time 5 import random 6 from matplotlib import pyplot as plt 7 import numpy as np 8 from numpy import genfromtxt 9 import matplotlib.pyplot as plt 10 import matplotlib 11 from scipy.optimize import leastsq 12 13 url = 'https://www.qidian.com/' 14 r = requests.get(url,timeout = 30) 15 r.raise_for_status() 16 r.encoding = 'urf-8' 17 r.text 18 html=r.text 19 soup=BeautifulSoup(html,'html.parser') 20 tictet=soup.find_all('i',class_='total') 21 name_1=soup.find_all('a',class_='name') 22 name=[] 23 for i in range(39,52): 24 name.append(name_1[i].text) 25 print('{:^50}'.format('熱門書籍')) 26 print('{:^5}\t{:^40}\t{:^10}'.format('排名', '書名', '推薦數')) 27 for i in range(13): 28 print('{:^5}\t{:^40}\t{:^10}'.format(i+1, name[i], tictet[i].text)) 29 lit=[] 30 for i in range(13): 31 lit.append([i+1, name[i], tictet[i].text]) 32 df = pd.DataFrame(lit,columns=['排名','書名','推薦數']) 33 df.to_excel('D:/python_work/python_1.xlsx')
2.
1 #讀取excel文件 2 rank=pd.DataFrame(pd.read_excel('D:/python_work/python_1.xlsx')) 3 print(rank)
3.
1 #刪除無效列 2 #rank.drop('書名',axis=1,inplace=True) 3 #print(rank)
4.
1 #檢查是否有重復值 2 print(rank.duplicated())
5.
1 #檢查是否有空值 2 print(rank['推薦數'].isnull().value_counts())
6.
1 #數據分析 2 from sklearn.linear_model import LinearRegression 3 X = df.drop("標題",axis=1) 4 predict_model = LinearRegression() 5 predict_model.fit(X,df['熱度']) 6 print("回歸系數為:",predict_model.coef_)
7.
1 #畫出散點圖 2 plt.rcParams['font.sans-serif'] = ['SimHei'] # 用來正常顯示中文標簽 3 plt.rcParams['axes.unicode_minus'] = False # 用來正常顯示負號 4 N=10 5 x=np.random.rand(N) 6 y=np.random.rand(N) 7 size=50 8 plt.xlabel("排名") 9 plt.ylabel("推薦數") 10 plt.scatter(x,y,size,color='r',alpha=0.5,marker="o") 11 #散點圖 kind='reg' 12 sns.jointplot(x="排名",y="推薦數",data=rank,kind='reg') 13 # kind='hex' 14 sns.jointplot(x="排名",y="推薦數",data=rank,kind='hex') 15 # kind='kde' 16 sns.jointplot(x="排名",y="推薦數",data=rank,kind="kde",space=0,color='g')
8.
1 #選擇排名和熱度兩個特征變量,繪制分布圖,用最小二乘法分析兩個變量間的二次擬合方程和擬合曲線 2 colnames=[" ","排名","書名","推薦數"] 3 df = pd.read_excel('rank.xlsx',skiprows=1,names=colnames) 4 X = df.排名 5 Y = df.推薦數 6 Z = df.書名 7 def A(): 8 plt.scatter(X,Y,color="blue",linewidth=2) 9 plt.title("RM scatter",color="blue") 10 plt.grid() 11 plt.show() 12 def B(): 13 plt.scatter(X,Y,color="green",linewidth=2) 14 plt.title("redu",color="blue") 15 plt.grid() 16 plt.show() 17 def func(p,x): 18 a,b,c=p 19 return a*x*x+b*x+c 20 def error(p,x,y): 21 return func(p,x)-y 22 def main(): 23 plt.figure(figsize=(10,6)) 24 p0=[0,0,0] 25 Para = leastsq(error,p0,args=(X,Y)) 26 a,b,c=Para[0] 27 print("a=",a,"b=",b,"c=",c) 28 plt.scatter(X,Y,color="blue",linewidth=2) 29 x=np.linspace(0,20,20) 30 y=a*x*x+b*x+c 31 plt.plot(x,y,color="blue",linewidth=2,) 32 plt.title("熱度值分布") 33 plt.grid() 34 plt.show() 35 print(A()) 36 print(B()) 37 print(main())
四、完整代碼
1 from bs4 import BeautifulSoup 2 import requests 3 import pandas as pd 4 import time 5 import random 6 from matplotlib import pyplot as plt 7 import numpy as np 8 from numpy import genfromtxt 9 import matplotlib.pyplot as plt 10 import matplotlib 11 from scipy.optimize import leastsq 12 13 url = 'https://www.qidian.com/' 14 r = requests.get(url,timeout = 30) 15 r.raise_for_status() 16 r.encoding = 'urf-8' 17 r.text 18 html=r.text 19 soup=BeautifulSoup(html,'html.parser') 20 tictet=soup.find_all('i',class_='total') 21 for i in range(len(tictet)): 22 print(tictet[i].text) 23 name_1=soup.find_all('a',class_='name') 24 name=[] 25 for i in range(39,52): 26 name.append(name_1[i].text) 27 print(name) 28 print('{:^50}'.format('熱門書籍')) 29 print('{:^5}\t{:^40}\t{:^10}'.format('排名', '書名', '推薦數')) 30 for i in range(13): 31 print('{:^5}\t{:^40}\t{:^10}'.format(i+1, name[i], tictet[i].text)) 32 lit=[] 33 for i in range(13): 34 lit.append([i+1, name[i], tictet[i].text]) 35 df = pd.DataFrame(lit,columns=['排名','書名','推薦數']) 36 df.to_excel('D:/python_work/python_1.xlsx') 37 #讀取excel文件 38 rank=pd.DataFrame(pd.read_excel('D:/python_work/python_1.xlsx')) 39 print(rank) 40 #刪除無效列 41 #rank.drop('書名',axis=1,inplace=True) 42 #print(rank) 43 #檢查是否有重復值 44 print(rank.duplicated()) 45 #檢查是否有空值 46 print(rank['推薦數'].isnull().value_counts()) 47 #異常值處理 48 print(rank.describe()) 49 #數據分析 50 from sklearn.linear_model import LinearRegression 51 X = df.drop("書名",axis=1) 52 predict_model = LinearRegression() 53 predict_model.fit(X,df['推薦數']) 54 print("回歸系數為:",predict_model.coef_) 55 #畫出散點圖 56 plt.rcParams['font.sans-serif'] = ['SimHei'] # 用來正常顯示中文標簽 57 plt.rcParams['axes.unicode_minus'] = False # 用來正常顯示負號 58 N=10 59 x=np.random.rand(N) 60 y=np.random.rand(N) 61 size=50 62 plt.xlabel("排名") 63 plt.ylabel("推薦數") 64 plt.scatter(x,y,size,color='r',alpha=0.5,marker="o") 65 #散點圖 kind='reg' 66 sns.jointplot(x="排名",y="推薦數",data=rank,kind='reg') 67 # kind='hex' 68 sns.jointplot(x="排名",y="推薦數",data=rank,kind='hex') 69 # kind='kde' 70 sns.jointplot(x="排名",y="推薦數",data=rank,kind="kde",space=0,color='g') 71 #選擇排名和熱度兩個特征變量,繪制分布圖,用最小二乘法分析兩個變量間的二次擬合方程和擬合曲線 72 colnames=[" ","排名","書名","推薦數"] 73 df = pd.read_excel('D:/python_work/python_1.xlsx',skiprows=1,names=colnames) 74 X = df.排名 75 Y = df.推薦數 76 Z = df.書名 77 def A(): 78 plt.scatter(X,Y,color="blue",linewidth=2) 79 plt.title("RM scatter",color="blue") 80 plt.grid() 81 plt.show() 82 def B(): 83 plt.scatter(X,Y,color="green",linewidth=2) 84 plt.title("redu",color="blue") 85 plt.grid() 86 plt.show() 87 def func(p,x): 88 a,b,c=p 89 return a*x*x+b*x+c 90 def error(p,x,y): 91 return func(p,x)-y 92 def main(): 93 plt.figure(figsize=(10,6)) 94 p0=[0,0,0] 95 Para = leastsq(error,p0,args=(X,Y)) 96 a,b,c=Para[0] 97 print("a=",a,"b=",b,"c=",c) 98 plt.scatter(X,Y,color="blue",linewidth=2) 99 x=np.linspace(0,20,20) 100 y=a*x*x+b*x+c 101 plt.plot(x,y,color="blue",linewidth=2,) 102 plt.title("熱度值分布") 103 plt.grid() 104 plt.show() 105 print(A()) 106 print(B()) 107 print(main())
五、總結
這次數據爬蟲,一開始感覺並沒有什么頭緒,不知道怎么開始,爬什么東西。但是在看了其他學姐學長的博客后,對於自己的爬蟲有了大致的方向。但是在實際做起來時還是遇到了很多的困難,比如一開始我是准備爬嗶哩嗶哩視頻網站的視頻信息的,但是得到的數字數據里面會帶有一個“萬”字,我並不知道怎么去掉,於是放棄了,換成了現在的爬起點中文網的書籍信息。這一次也是有一個難點的,就是爬出需要的書名的時候還爬出的其他分類里面的書名,我看了一下,發現這些地方的標簽和屬性都一樣,就很離譜。雖然我不會這么去把它具體的分離出來,但是每一個分類的書名數是固定的,於是我就用了一個死辦法,數!最終把這個博文寫了出來。
最后想想還是很激動的,因為自己把這么一個東西寫出來,成就感很充足。