一、選題的背景 為什么要選擇此選題?要達到的數據分析的預期目標是什么?(10 分) 從社會、經濟、技術、數據來源等方面進行描述(200 字以內)
通過爬取數據后數據分析能夠直觀的看到二手車市場中某一品牌的相對數據,能夠了解到現在的二手車市場情況,通過分析數據看到二手車的走勢,車商就可以利用這些數據進行定價,讓想買二手車卻不了解市場的人了解到大概的價格走勢,到了店里不會被騙。
二、主題式網絡爬蟲設計方案(10 分)
1.主題式網絡爬蟲名稱
基於BeautifulSoup的二手車信息爬取和分析
2.主題式網絡爬蟲爬取的內容與數據特征分析
利用requests和BeautifulSoup爬取瓜子二手車網信息,爬取內容包括二手車的型號、價格、車齡、里程,然后清洗數據后獲得自己想要的數據信息。其數據特征表現為:經過數據清洗后獲得的數據沒有重復值和無效值,讓數據更具有說服力。
3.主題式網絡爬蟲設計方案概述(包括實現思路與技術難點)
實現思路:繞過反爬獲取網頁資源,使用etree解析網頁,用xpath定位爬取內容標簽后爬取資源並將數據保存到csv文件中。
技術難點:設置請求頭,for循環實現重復爬取
三、主題頁面的結構特征分析(10 分)
1.主題頁面的結構與特征分析
鏈接如下:https://www.guazi.com/fz/audi/

2.Htmls 頁面解析

3.節點(標簽)查找方法與遍歷方法 (必要時畫出節點樹結構)
查找方法:find_all
遍歷方法:for循環遍歷
四、網絡爬蟲程序設計(60 分)
爬蟲程序主體要包括以下各部分,要附源代碼及較詳細注釋,並在每部分程序后 面提供輸出結果的截圖。
- 數據爬取與采集
1 #導入庫 2 import requests 3 from lxml import etree 4 import time 5 import re 6 import pandas as pd 7 8 #初始化空列表 9 carname_lis,carage_lis, price_lis, mileage_lis = [], [], [], [] 10 11 12 for a in range(10): 13 #爬取網站的網址並且循環爬取前10頁的內容 14 url = "https://www.guazi.com/fz/audi/{}/#bread".format(a*10) 15 16 #設置請求頭 17 headers = { 18 "User-Agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4430.93 Safari/537.36" 19 } 20 #requests請求鏈接 21 resp = requests.get(url,headers=headers).text 22 23 #使用lxml模塊中的etree方法講字符串轉化為html標簽 24 html = etree.HTML(resp) 25 26 #用xpath定位標簽位置 27 lis = html.xpath("/html/body/div[6]/ul/li") 28 29 #獲取要爬取內容的詳情鏈接 30 for li in lis: 31 #爬取車名 32 carname = li.xpath("./a/h2/text()")[0] 33 #爬取車齡 34 carage = li.xpath("./a/div[1]/text()")[0] 35 #爬取里程 36 milrage = li.xpath("./a/div[1]/text()[2]")[0] 37 #爬取價格 38 price = li.xpath("./a/div[2]/p/text()")[0] 39 40 #輸出 41 print(carname) 42 print(carage) 43 print(milrage) 44 print(price) 45 # 將字段存入初始化的列表中 46 carname_lis.append(carname) 47 carage_lis.append(carage) 48 mileage_lis.append(milrage) 49 price_lis.append(price) 50 51 #pandas中的模塊將數據存入 52 df = pd.DataFrame({ 53 "型號" : carname_lis, 54 "車齡" : carage_lis, 55 "里程" : mileage_lis, 56 "價格" : price_lis, 57 }) 58 #儲存為csv文件 59 df.to_csv("aodi.csv" , encoding='utf_8_sig', index=False)

2.對數據進行清洗和處理
1 #導入庫 2 import pandas as pd 3 import numpy as mp 4 import sklearn 5 import seaborn as sns 6 import matplotlib.pyplot as plt 7 #讀取csv文件 8 aodi = pd.DataFrame(pd.read_csv('aodi.csv')) 9 aodi.head()

1 #檢查重復值 2 aodi.duplicated()

1 #刪除重復值 2 aodi = aodi.drop_duplicates() 3 aodi.head()

1 #清洗文字左右空格 2 aodi['型號'] = aodi['型號'].map(str.strip) 3 aodi['車齡'] = aodi['車齡'].map(str.strip) 4 aodi['里程'] = aodi['里程'].map(str.strip) 5 aodi.head()

3.文本分析(可選):jieba 分詞、wordcloud 的分詞可視化
4.數據分析與可視化(例如:數據柱形圖、直方圖、散點圖、盒圖、分布圖)
1 #價格直方圖 2 sns.distplot(aodi['價格'])

1 #車齡占比餅圖 2 plt.rcParams['font.sans-serif'] = ['SimHei']#解決亂碼問題 3 df_score = aodi['車齡'].value_counts() #統計評分情況 4 plt.title("車齡占比圖") #設置餅圖標題 5 plt.pie(df_score.values,labels = df_score.index,autopct='%1.1f%%') #繪圖 6 #autopct表示圓里面的文本格式,在python里%操作符可用於格式化字符串操作 7 plt.show()

5.根據數據之間的關系,分析兩個變量之間的相關系數,畫出散點圖,並建立變 量之間的回歸方程(一元或多元)。
1 #繪制散點圖查看關系 2 sns.regplot(x = '價格',y = '車齡',data=aodi)

1 import pandas as pd 2 import numpy as mp 3 import sklearn 4 import seaborn as sns 5 import matplotlib.pyplot as plt 6 from scipy.optimize import leastsq 7 plt.rcParams['font.sans-serif'] = ['SimHei']#解決亂碼問題 8 #讀取文件 9 aodi = pd.DataFrame(pd.read_csv('aodi.csv')) 10 #定義變量 11 price=aodi.loc[:,'價格'] 12 year=aodi.loc[:,'年'] 13 #函數表達式 14 def func(params,x): 15 a,b,c=params 16 return a*x*x+b*x+c 17 def error_func(params,x,y): 18 return func(params,x)-y 19 P0=[1,9.0] 20 def main(): 21 plt.figure(figsize=(8,6)) 22 P0=[1,9.0,1] 23 Para=leastsq(error_func,P0,args=(price,year)) 24 a,b,c=Para[0] 25 print("a=",a, "b=",b, "c=",c) 26 #繪圖 27 plt.scatter(price,year,color="green",label="樣本數據",linewidth=2) 28 x=mp.linspace(1,50,40) 29 y=a*x*x+b*x+c 30 #右上角標 31 plt.plot(x,y,color="red",label="擬合曲線",linewidth=2) 32 #x,y軸名稱 33 plt.xlabel('價格') 34 plt.ylabel('車齡') 35 #標題 36 plt.title("價格與車齡回歸方程") 37 plt.grid() 38 plt.legend() 39 plt.show() 40 main()

6.數據持久化
1 #儲存為csv 2 df.to_csv("aodi.csv" , encoding='utf_8_sig', index=False)
7.將以上各部分的代碼匯總,附上完整程序代碼
1 #導入庫 2 import requests 3 from lxml import etree 4 import time 5 import re 6 import pandas as pd 7 8 #初始化空列表 9 carname_lis,carage_lis, price_lis, mileage_lis = [], [], [], [] 10 11 12 for a in range(10): 13 #爬取網站的網址並且循環爬取前10頁的內容 14 url = "https://www.guazi.com/fz/audi/{}/#bread".format(a*10) 15 16 #設置請求頭 17 headers = { 18 "User-Agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4430.93 Safari/537.36" 19 } 20 #requests請求鏈接 21 resp = requests.get(url,headers=headers).text 22 23 #使用lxml模塊中的etree方法講字符串轉化為html標簽 24 html = etree.HTML(resp) 25 26 #用xpath定位標簽位置 27 lis = html.xpath("/html/body/div[6]/ul/li") 28 29 #獲取要爬取內容的詳情鏈接 30 for li in lis: 31 #爬取車名 32 carname = li.xpath("./a/h2/text()")[0] 33 #爬取車齡 34 carage = li.xpath("./a/div[1]/text()")[0] 35 #爬取里程 36 milrage = li.xpath("./a/div[1]/text()[2]")[0] 37 #爬取價格 38 price = li.xpath("./a/div[2]/p/text()")[0] 39 40 #輸出 41 print(carname) 42 print(carage) 43 print(milrage) 44 print(price) 45 # 將字段存入初始化的列表中 46 carname_lis.append(carname) 47 carage_lis.append(carage) 48 mileage_lis.append(milrage) 49 price_lis.append(price) 50 51 #pandas中的模塊將數據存入 52 df = pd.DataFrame({ 53 "型號" : carname_lis, 54 "車齡" : carage_lis, 55 "里程" : mileage_lis, 56 "價格" : price_lis, 57 }) 58 #儲存為csv文件 59 df.to_csv("aodi.csv" , encoding='utf_8_sig', index=False) 60 61 #導入庫 62 import pandas as pd 63 import numpy as mp 64 import sklearn 65 import seaborn as sns 66 import matplotlib.pyplot as plt 67 #讀取csv文件 68 aodi = pd.DataFrame(pd.read_csv('aodi.csv')) 69 aodi.head() 70 #檢查重復值 71 aodi.duplicated() 72 #刪除重復值 73 aodi = aodi.drop_duplicates() 74 aodi.head() 75 76 #清洗文字左右空格 77 aodi['型號'] = aodi['型號'].map(str.strip) 78 aodi['車齡'] = aodi['車齡'].map(str.strip) 79 aodi['里程'] = aodi['里程'].map(str.strip) 80 aodi.head() 81 82 #價格直方圖 83 sns.distplot(aodi['價格']) 84 85 86 #車齡占比餅圖 87 plt.rcParams['font.sans-serif'] = ['SimHei']#解決亂碼問題 88 df_score = aodi['車齡'].value_counts() #統計評分情況 89 plt.title("車齡占比圖") #設置餅圖標題 90 plt.pie(df_score.values,labels = df_score.index,autopct='%1.1f%%') #繪圖 91 #autopct表示圓里面的文本格式,在python里%操作符可用於格式化字符串操作 92 plt.show() 93 94 #繪制散點圖查看關系 95 sns.regplot(x = '價格',y = '車齡',data=aodi) 96 97 #儲存為csv文件 98 df.to_csv("aodi.csv" , encoding='utf_8_sig', index=False)
五、總結(10 分)
1.經過對主題數據的分析與可視化,可以得到哪些結論?
(1)14、19、16這三個年份的二手車比較多,老車反而比較少
(2)價格較高的車都是19、20、21這三個年份的
(3)可視化的數據相當直觀,一眼就能找到需要的
2.在完成此設計過程中,得到哪些收獲?以及要改進的建議?
在這次的設計過程中,很多東西都是自己一步一步摸索的,因為有些代碼就算一樣復制過來也用不了,雖然這次沒有完全實現,也還存在一些問題,在解決一個又一個問題之后,我自己也對python這門語言有了更深的理解,也越發覺得有趣。希望自己下次在繪圖上可以做的更好。
