一、主題式網絡爬蟲設計方案
1.主題式網絡爬蟲名稱:爬取豆瓣讀書top250
2.主題式網絡爬蟲爬取的內容:書名,價格,出版時間,作者,翻譯者,評論人數,評分
3.主題式網絡爬蟲設計方案概述:
思路:分析網頁源代碼,找出數據所在的標簽,通過爬蟲讀取數據存入excel,對數據清洗分析
難點:爬取數據數量太多,所掌握的知識不夠使用,爬取到的數據全都不是單純的數字,所以在數據處理時遇到了許多問題
二、主題頁面的結構特征分析
1.主題頁面的結構與特征分析
爬取數據都分布在標簽'<div id="content">'里,書名標簽為'div class="pl2"',評分標簽為'span.class="rating_nums"等
2.Htmls頁面解析


三、網絡爬蟲程序設計
1.數據爬取與采集
import requests from lxml import etree import csv import pandas as pd import matplotlib.pyplot as plt import seaborn as sns headers={ 'User-Agent':'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36' '(KHTML, like Gecko) Chrome/70.0.3538.25 Safari/537.36 Core/1.70.3775.400 QQBrowser/10.6.4209.400' } def get_one_page(url): url = 'https://book.douban.com/top250?start=0' response = requests.get(url,headers=headers) #將網頁數據裝換成Html對象 html = etree.HTML(response.text) book_name = html.xpath('//div[@class="pl2"]/a/@title') #爬取書名 rating_nums = html.xpath('//span[@class="rating_nums"]/text()') #爬取評價分數 raint_people_ = html.xpath('//span[@class="pl"]/text()') #爬取評價人數 raint_people = [] for i in raint_people_: raint_people.append(i.strip('()\n 人評價')) book_infos = html.xpath('//p[@class="pl"]/text()')#爬取書籍信息 author = [] translator = [] publisher = [] time = [] price = [] for j in book_infos: data = j.split('/') author.append(data[0]) translator.append(data[1] if len(data) == 5 else ' ') publisher.append(data[-3]) time.append(data[-2]) price.append(data[-1]) book_data = [] for i in range(25): book_data.append([book_name[i],author[i],translator[i],publisher[i],time[i],price[i],rating_nums[i],raint_people[i]]) print(book_data) return book_data #數據持久化 with open('豆瓣top250.csv',mode='w',newline='',encoding='utf-8') as f: writer = csv.writer(f) writer.writerow(['書名','作者','翻譯者','出版社','出版日期','價格','評分','評價人數']) for i in range(10): print('頁數'+str(i+1)) link = 'https://book.douban.com/top250?start=' + str(i*25) for i in get_one_page(link): writer.writerow(i)


2.對數據進行清洗和處理
df = pd.DataFrame(pd.read_csv('豆瓣top250.csv'))#數據進行清洗和處理 df.head()

df.duplicated()#檢查是否有重復值

df.isnull().sum()#控制處理

df[df.isnull().values==True]#缺失值處理

df.describe()#用describe()命令顯示描述性統計指標

3.數據分析與可視化
#繪制評價人數與評分柱狀圖 plt.rcParams['axes.unicode_minus']=False #用來正常顯示負號 plt.bar(df.評分, df.評價人數, label="評價人數與評分柱狀圖") plt.show() plt.rcParams['font.sans-serif']=['STSong']

#繪制評價人數與評分散點圖 def Scatter_point(): plt.scatter(df.價格, df.評分, color='red', s=25, marker="o") plt.xlabel("評價人數") plt.ylabel("評分") plt.title("評價人數與評分-散點圖") plt.show() Scatter_point()

#繪制排名與評分-盒圖 def draw1(): plt.figure(figsize=(10, 6)) plt.title('繪制評價人數與評分-盒圖') sns.boxplot(x='評價人數',y='評分', data=df) draw1()

#繪制評價人數與評分的回歸圖 plt.rcParams['font.sans-serif']=['STSong']#顯示中文 sns.regplot(df.評價人數,df.評分)

#繪制部分分布圖 sns.jointplot(x="評價人數",y='評分',data = df, kind='re

#繪制排名與熱度折線圖 def draw(): x = df['評價人數'] y = df['評分'] plt.xlabel('評價人數') plt.ylabel('評分') plt.plot(x,y) plt.scatter(x,y) plt.title("繪制評價人數與評分折線圖") plt.show() draw()

#繪制部分分布圖 sns.jointplot(x="評價人數",y='評分',data = df, kind='kde', color='r') sns.jointplot(x="評價人數",y='評分',data = df) sns.jointplot(x="評價人數",y='評分',data = df, kind='reg') sns.jointplot(x="評價人數",y='評分',data = df, kind='hex')




#繪制一元一次回歸方程 import numpy as np from scipy.optimize import leastsq import pandas as pd def main(): colnames = ["價格", "評分"] df = pd.read_csv('豆瓣top250.csv',skiprows=1,names=colnames) X = df.價格 Y = df.評分 def func(p, x): k, b = p return k * x + b def error_func(p, x, y): return func(p,x)-y p0 = [0,0] Para = leastsq(error_func, p0, args = (X, Y)) k, b = Para[0] print("k=",k,"b=",b) plt.figure(figsize=(10,6)) plt.scatter(X,Y,color="green",label=u"評分分布",linewidth=2) x=np.linspace(0,30,20) y=k*x+b plt.plot(x,y,color="red",label=u"回歸方程直線",linewidth=2) plt.title("豆瓣top250") plt.xlabel('價格') plt.ylabel('評分') plt.legend() plt.show() main()

5.數據持久化
#數據持久化 with open('豆瓣top250.csv',mode='w',newline='',encoding='utf-8') as f: writer = csv.writer(f) writer.writerow(['書名','作者','翻譯者','出版社','出版日期','價格','評分','評價人數']) for i in range(10): print('頁數'+str(i+1)) link = 'https://book.douban.com/top250?start=' + str(i*25) for i in get_one_page(link): writer.writerow(i)
6.將以上各部分的代碼匯總,附上完整程序代碼:
# -*- coding: utf-8 -*-
"""
Created on Wed Sep 23 08:17:48 2020
@author: Administrator
"""
#數據爬取和采集
import requests
from lxml import etree
import csv
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
headers={
'User-Agent':'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36' '(KHTML, like Gecko) Chrome/70.0.3538.25 Safari/537.36 Core/1.70.3775.400 QQBrowser/10.6.4209.400'
}
def get_one_page(url):
url = 'https://book.douban.com/top250?start=0'
response = requests.get(url,headers=headers)
#將網頁數據裝換成Html對象
html = etree.HTML(response.text)
book_name = html.xpath('//div[@class="pl2"]/a/@title') #爬取書名
rating_nums = html.xpath('//span[@class="rating_nums"]/text()') #爬取評價分數
raint_people_ = html.xpath('//span[@class="pl"]/text()') #爬取評價人數
raint_people = []
for i in raint_people_:
raint_people.append(i.strip('()\n 人評價'))
book_infos = html.xpath('//p[@class="pl"]/text()')#爬取書籍信息
author = []
translator = []
publisher = []
time = []
price = []
for j in book_infos:
data = j.split('/')
author.append(data[0])
translator.append(data[1] if len(data) == 5 else ' ')
publisher.append(data[-3])
time.append(data[-2])
price.append(data[-1])
book_data = []
for i in range(25):
book_data.append([book_name[i],author[i],translator[i],publisher[i],time[i],price[i],rating_nums[i],raint_people[i]])
print(book_data)
return book_data
#數據持久化
with open('豆瓣top250.csv',mode='w',newline='',encoding='utf-8') as f:
writer = csv.writer(f)
writer.writerow(['書名','作者','翻譯者','出版社','出版日期','價格','評分','評價人數'])
for i in range(10):
print('頁數'+str(i+1))
link = 'https://book.douban.com/top250?start=' + str(i*25)
for i in get_one_page(link):
writer.writerow(i)
#讀取CSV文件
df = pd.DataFrame(pd.read_csv('豆瓣top250.csv'))#數據進行清洗和處理
df.head()
df.duplicated()#檢查是否有重復值
df.isnull().sum()#控制處理
df[df.isnull().values==True]#缺失值處理
df.describe()#用describe()命令顯示描述性統計指標
#數據可視化
#繪制評價人數與評分柱狀圖
plt.rcParams['axes.unicode_minus']=False #用來正常顯示負號
plt.bar(df.評分, df.評價人數, label="評價人數與評分柱狀圖")
plt.show()
plt.rcParams['font.sans-serif']=['STSong']
#繪制評價人數與評分散點圖
def Scatter_point():
plt.scatter(df.價格, df.評分, color='red', s=25, marker="o")
plt.xlabel("評價人數")
plt.ylabel("評分")
plt.title("評價人數與評分-散點圖")
plt.show()
Scatter_point()
#繪制排名與評分-盒圖
def draw1():
plt.figure(figsize=(10, 6))
plt.title('繪制評價人數與評分-盒圖')
sns.boxplot(x='評價人數',y='評分', data=df)
draw1()
#繪制評價人數與評分的回歸圖
plt.rcParams['font.sans-serif']=['STSong']#顯示中文
sns.regplot(df.評價人數,df.評分)
#繪制部分分布圖
sns.jointplot(x="評價人數",y='評分',data = df, kind='reg')
#繪制排名與熱度折線圖
def draw():
x = df['評價人數']
y = df['評分']
plt.xlabel('評價人數')
plt.ylabel('評分')
plt.plot(x,y)
plt.scatter(x,y)
plt.title("繪制評價人數與評分折線圖")
plt.show()
draw()
#繪制部分分布圖
sns.jointplot(x="評價人數",y='評分',data = df, kind='kde', color='r')
sns.jointplot(x="評價人數",y='評分',data = df)
sns.jointplot(x="評價人數",y='評分',data = df, kind='reg')
sns.jointplot(x="評價人數",y='評分',data = df, kind='hex')
四、結論
1.結論:經過對主題數據的分析與可視化,突出了各數據間的關系和各數據呈現出來的分布,通過數據分析和可視化讓抽象的數據變成具體的圖像,讓我們的理解更加容易,解決了大部分人工計算繪圖等繁雜過程,能夠通過爬蟲爬取信息並運用其他庫處理信息對工作效率的提升是多么的大,提高了自己對python的興趣,堅定了認真學習的目標。
2.小結:通過這次做題任務,我明白了數據的分析與可視化,掌握了不少庫的使用,期間有在百度上等地方進行學習,此次任務有所收獲,加深了對python的熱愛通過這次做題任務,我在完成的過程中遇到了很多的困難,讓我得到了許多收獲,也讓我充分的認識到了自己的不足之處,在未來我將更加努力的學習。
