一、选题背景
通过爬取起点中文网热门小说信息,可以时实的了解到现在,热门小说的写作方向、主题等,也可以大致了解读者对小说的消费情况。
二、主题式网络爬虫设计方案
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())
五、总结
这次数据爬虫,一开始感觉并没有什么头绪,不知道怎么开始,爬什么东西。但是在看了其他学姐学长的博客后,对于自己的爬虫有了大致的方向。但是在实际做起来时还是遇到了很多的困难,比如一开始我是准备爬哔哩哔哩视频网站的视频信息的,但是得到的数字数据里面会带有一个“万”字,我并不知道怎么去掉,于是放弃了,换成了现在的爬起点中文网的书籍信息。这一次也是有一个难点的,就是爬出需要的书名的时候还爬出的其他分类里面的书名,我看了一下,发现这些地方的标签和属性都一样,就很离谱。虽然我不会这么去把它具体的分离出来,但是每一个分类的书名数是固定的,于是我就用了一个死办法,数!最终把这个博文写了出来。
最后想想还是很激动的,因为自己把这么一个东西写出来,成就感很充足。