零、實驗要求
1.爬取數據
2.對數據進行可視化,要求橫軸是競價日期,縱軸表現其他各屬性
一、獲取數據
實驗用到的數據是這樣的,你可以右鍵選擇新建標籤頁打開圖片看到它
獲取該.xlsx文件的爬蟲代碼是——
import re
import requests
import pandas as pd
from bs4 import BeautifulSoup
wang=[];
for k in range(2,5):
url="http://xkctk.hangzhou.gov.cn/tzgg/index_{0}.html".format(k)
r=requests.get(url)
r.encoding="utf-8"
soup=BeautifulSoup(r.text,"html.parser")
a=soup.find_all('a',string=re.compile('增量指標競價情況'))
for links in a:
urll=links.get("href")
rr=requests.get(urll)
rr.encoding="utf-8"
soupp=BeautifulSoup(rr.text,"html.parser")
result=re.findall(r'\d+\-\d+\-\d+|配置增量指標\d+|個人增量指標\d+|單位增量指標\d+|最低成交價[\u4e00-\u9fa5]+\d+\元\D\單位\d+|成交\d+|平均成交價[\u4e00-\u9fa5]+\d+\元\D\單位\d+',soupp.text)
lis=[str(i) for i in result]
l="".join(lis)
title=['競價日期','配置增量指標','個人增量指標','單位增量指標','個人最低成交價','單位最低成交價','個人最低成交價個數','單位最低成交價個數','個人平均成交價','單位平均成交價']
number=re.findall(r'\d+\-\d+\-\d+|\d+',l)
result1=dict(zip(title,number))
wang.append(result1)
writer = pd.ExcelWriter('news.xlsx') #news爲文件名
df=pd.DataFrame(wang) #將字典保存成DataFrame數據結構
df.to_excel(writer,index=False,columns=('競價日期','配置增量指標','個人增量指標','單位增量指標','個人最低成交價','單位最低成交價','個人最低成交價個數','單位最低成交價個數','個人平均成交價','單位平均成交價')) #導出成excel
df.to_excel('C:/暫用/news.xlsx')
二、繪製單個柱狀圖的代碼
單獨一對一的圖
"""個人最低成交價/日期"""
import matplotlib.pyplot as plt
import pandas as pd
# 解決中文和負號顯示問題
plt.rcParams['font.sans-serif']=['SimHei']
plt.rcParams['axes.unicode_minus'] = False
df = pd.read_excel("news.xlsx", "Sheet1") # 讀取news.xlsx文件的Sheet1
fig = plt.figure()
plt.bar(df['競價日期'], df['個人最低成交價']) # plt.bar(x,y)
plt.title(u'個人最低成交價/日期')
plt.xlabel('日期', size=10)
plt.ylabel(u'個人最低成交價')
plt.show()
三、繪製多柱狀圖並標上數值的代碼
由於整體數值相差較大(如最低成交個數和最低成交價的數值差距),這裏分成兩段代碼,分別顯示
第1個.py
"""配置增量指標/日期"""
import matplotlib.pyplot as plt
import pandas as pd
total_width, n = 0.8, 4 # 對每一個日期設置0.8的寬度,有9個指標
width = total_width / n # 每個日期下每個指標的寬度
# 定義函數來顯示柱狀上的數值
def autolabel(rects):
for rect in rects:
height = rect.get_height()
plt.text(rect.get_x() + rect.get_width() / n - 0.1, height + 1000, '%s' % float(height))
# 解決中文和負號顯示問題
plt.rcParams['font.sans-serif'] = ['SimHei']
plt.rcParams['axes.unicode_minus'] = False
df = pd.read_excel("news.xlsx", "Sheet1")
fig = plt.figure()
x = [0, 1, 2, 3, 4, 5, 6, 7] # 一共有8行數據
# 每繪製過一個指標,就加上一定的寬度使下一個指標的柱狀圖不重疊##
for i in range(len(x)): ##
x[i] = x[i] + width ##
################################################################
# 橫座標爲x,縱座標爲df['個人最低成交價'], 寬度爲width
t3 = plt.bar(x, df['個人最低成交價'], width=width, label='個人最低成交價', fc='b') # 顏色爲blue
for i in range(len(x)):
x[i] = x[i] + width
# tick_label:此處真正顯示日期
t4 = plt.bar(x, df['單位最低成交價'], width=width, tick_label=df['競價日期'], label='單位最低成交價', fc='g')# 顏色爲green
for i in range(len(x)):
x[i] = x[i] + width
t7 = plt.bar(x, df['個人平均成交價'], width=width, label='個人平均成交價', fc='r') # 顏色爲red
for i in range(len(x)):
x[i] = x[i] + width
t8 = plt.bar(x, df['單位平均成交價'], width=width, label='單位平均成交價', fc='c') # 顏色爲青色
autolabel(t3)
autolabel(t4)
autolabel(t7)
autolabel(t8)
plt.title(u'x/日期')
plt.xlabel('日期', size=10)
plt.ylabel(u'各項指標')
plt.legend()
plt.show()
第2個.py
"""配置增量指標/日期"""
import matplotlib.pyplot as plt
import pandas as pd
total_width, n = 0.8, 5 # 對每一個日期設置0.8的寬度,有n個指標
width = total_width / n # 每個日期下每個指標的寬度
# 定義函數來顯示柱狀上的數值
def autolabel(rects):
for rect in rects:
height = rect.get_height()
# 在(rect.get_x() + rect.get_width() / n, height + 10)座標處,寫上文本height
plt.text(rect.get_x() + rect.get_width() / n, height + 10, '%s' % float(height))
# 解決中文和負號顯示問題
plt.rcParams['font.sans-serif'] = ['SimHei']
plt.rcParams['axes.unicode_minus'] = False
df = pd.read_excel("news.xlsx", "Sheet1")
fig = plt.figure()
x = [0, 1, 2, 3, 4, 5, 6, 7] # 一共有8行數據
t0 = plt.bar(x, df['配置增量指標'], width=width, label='配置增量指標', fc='y')
for i in range(len(x)):
x[i] = x[i] + width
t1 = plt.bar(x, df['個人增量指標'], width=width, label='個人增量指標', fc='r')
for i in range(len(x)):
x[i] = x[i] + width
t2 = plt.bar(x, df['單位增量指標'], width=width, tick_label=df['競價日期'], label='單位增量指標', fc='c')
for i in range(len(x)):
x[i] = x[i] + width
t5 = plt.bar(x, df['個人最低成交價個數'], width=width, label='個人最低成交價個數', fc='g')
for i in range(len(x)):
x[i] = x[i] + width
t6 = plt.bar(x, df['單位最低成交價個數'], width=width, label='單位最低成交價個數', fc='b')
autolabel(t0)
autolabel(t1)
autolabel(t2)
autolabel(t5)
autolabel(t6)
plt.title(u'x/日期')
plt.xlabel('日期', size=10)
plt.ylabel(u'各項指標')
plt.legend()
plt.show()