文章目錄
- 0 前言
- 1 課題背景
- 2 實作效果
- 3 Flask架構
- 4 Echarts
- 5 爬蟲
- 6 最後
0 前言
🔥 Hi,大家好,這裡是丹成學長的畢設系列文章!
🔥 對畢設有任何疑問都可以問學長哦!
這兩年開始,各個學校對畢設的要求越來越高,難度也越來越大… 畢業設計耗費時間,耗費精力,甚至有些題目即使是專業的老師或者碩士生也需要很長時間,是以一旦發現問題,一定要提前準備,避免到後面措手不及,草草了事。
為了大家能夠順利以及最少的精力通過畢設,學長分享優質畢業設計項目,今天要分享的新項目是
🚩 flask疫情爬蟲可視化
🥇學長這裡給一個題目綜合評分(每項滿分5分)
- 難度系數:4分
- 工作量:4分
- 創新點:3分
🧿 選題指導, 項目分享:
https://gitee.com/yaa-dc/BJH/blob/master/gg/cc/README.md
1 課題背景
自2019年12月12日武漢确診新型冠狀病毒患者開始,曆時三年之久的新冠疫情仍未結束。新型冠狀病毒肺炎(COVID-19)存在人畜跨界傳播、傳染性強、影響因素多樣、傳播途徑複雜等特點,導緻肺炎疫情發病急、發展快、溯源分析難、社會危害大等問題。随着新型冠狀病毒毒株的不斷變異,現出現了傳播性極強、免疫逃逸能力極高的變異病毒。
為更直覺、更專業地了解疫情的變化,本文設計了基于爬蟲、Dianjo、Pyecharts的COVID-19疫情資訊可視化系統。該系統主要包括疫情模型預測、疫情資訊可視化以及防疫措施指南三大功能,能夠實時動态展示疫情發展趨勢,并根據預測模型進行疫情預測以及提供有效的防疫措施。
2 實作效果
首頁
動畫展示
省份統計
省排名
3 Flask架構
簡介
Flask是一個基于Werkzeug和Jinja2的輕量級Web應用程式架構。與其他同類型架構相比,Flask的靈活性、輕便性和安全性更高,而且容易上手,它可以與MVC模式很好地結合進行開發。Flask也有強大的定制性,開發者可以依據實際需要增加相應的功能,在實作豐富的功能和擴充的同時能夠保證核心功能的簡單。Flask豐富的插件庫能夠讓使用者實作網站定制的個性化,進而開發出功能強大的網站。
本項目在Flask開發後端時,前端請求會遇到跨域的問題,解決該問題有修改資料類型為jsonp,采用GET方法,或者在Flask端加上響應頭等方式,在此使用安裝Flask-CORS庫的方式解決跨域問題。此外需要安裝請求庫axios。
Flask架構圖
相關代碼:
from flask import Flask, render_template
import csv
import codecs
web = Flask(__name__)
# 首頁
@web.route('/')
def index():
return render_template('index.html')
# 疫情可視化動畫展示子產品
@web.route('/movie')
def movie_list():
movies = [{'file':'top10省現有确診病例對比.mp4','title':'Top10省現有确診病例對比'},
{'file':'Top15國現有确診病例對比.mp4','title':'Top15國現有确診病例對比'}]
return render_template('movie.html',movies=movies)
# 中國新冠疫情實時資料地圖子產品
@web.route('/map')
def map():
return render_template('map.html')
# 今日發生疫情省份統計子產品
@web.route('/pie')
def pie():
with codecs.open(filename='../data/china_data.csv', mode='r', encoding='utf-8') as f:
reader = csv.reader(f)
head = next(reader)
today_confirm1 = {}
today_confirm2 = []
for item in reader:
args = tuple(item)
today_confirm1.update({args[2]: args[3]})
for key, value in today_confirm1.items():
if (value != '0'):
# today_confirm2.append({key: value})
today_confirm2.append({'name': key, 'value': value})
print(today_confirm2)
return render_template('pie.html',today_confirm=today_confirm2)
# 各省累計确診排名子產品
@web.route('/rank')
def rank():
with codecs.open('../data/china_data.csv', mode='r', encoding='utf-8') as f:
reader = csv.reader(f)
head = next(reader)
province_name = []
province_confirm = []
for item in reader:
args = tuple(item)
# print(args)
province_name.append(args[2])
province_confirm.append(args[9])
print(province_name)
print(province_confirm)
return render_template('rank.html', province_name=province_name,province_confirm=province_confirm)
web.run(debug=True)
4 Echarts
ECharts(Enterprise Charts)是百度開源的資料可視化工具,底層依賴輕量級Canvas庫ZRender。相容了幾乎全部常用浏覽器的特點,使它可廣泛用于PC用戶端和手機用戶端。ECharts能輔助開發者整合使用者資料,創新性的完成個性化設定可視化圖表。支援折線圖(區域圖)、柱狀圖(條狀圖)、散點圖(氣泡圖)、K線圖、餅圖(環形圖)等,通過導入 js 庫在 Java Web 項目上運作。
5 爬蟲
簡介
Scrapy是基于Twisted的爬蟲架構,它可以從各種資料源中抓取資料。其架構清晰,子產品之間的耦合度低,擴充性極強,爬取效率高,可以靈活完成各種需求。能夠友善地用來處理絕大多數反爬網站,是目前Python中應用最廣泛的爬蟲架構。Scrapy架構主要由五大元件組成,它們分别是排程器(Scheduler)、下載下傳器(Downloader)、爬蟲(Spider)和實體管道(Item Pipeline)、Scrapy引擎(Scrapy Engine)。各個元件的作用如下:
- 排程器(Scheduler):說白了把它假設成為一個URL(抓取網頁的網址或者說是連結)的優先隊列,由它來決定下一個要抓取的網址是 什麼,同時去除重複的網址(不做無用功)。使用者可以自己的需求定制排程器。
- 下載下傳器(Downloader):是所有元件中負擔最大的,它用于高速地下載下傳網絡上的資源。Scrapy的下載下傳器代碼不會太複雜,但效率高,主要的原因是Scrapy下載下傳器是建立在twisted這個高效的異步模型上的(其實整個架構都在建立在這個模型上的)。
- 爬蟲(Spider):是使用者最關心的部份。使用者定制自己的爬蟲(通過定制正規表達式等文法),用于從特定的網頁中提取自己需要的資訊,即所謂的實體(Item)。 使用者也可以從中提取對外連結接,讓Scrapy繼續抓取下一個頁面。
- 實體管道(Item Pipeline):用于處理爬蟲(spider)提取的實體。主要的功能是持久化實體、驗證明體的有效性、清除不需要的資訊。
- Scrapy引擎(Scrapy Engine):Scrapy引擎是整個架構的核心.它用來控制調試器、下載下傳器、爬蟲。實際上,引擎相當于計算機的CPU,它控制着整個流程。
官網架構圖
相關代碼:
# -*- coding: utf-8 -*-
import scrapy
import random
import time
from foodwake.items import FoodwakespiderItem
class FoodwakeSpider(scrapy.Spider):
name = 'foodwake'
allowed_domains = ['www.foodwake.com']
start_urls = ['http://www.foodwake.com/category/food-class/0']
# //:比對任意位置的節點 @:比對屬性
def parse(self, response):
for box in response.xpath('//div[@class="row margin-b2"]//a'):
new_url = box.xpath('.//@href').extract()[0]
yield scrapy.http.Request(new_url, callback=self.parse_item)
def parse_item(self, response):
for box in response.xpath('//div[@class="row margin-b2"]//a'):
new_url = box.xpath('.//@href').extract()[0]
yield scrapy.http.Request(new_url, meta={"url": new_url}, callback=self.parse_item_info)
def parse_item_info(self, response):
item = FoodwakespiderItem()
name = response.xpath('//h1[@class="color-yellow"]/text()').extract()[0].strip()
# food_nickname = ""
# try:
# nicknames = response.xpath('//h2[@class="h3 text-light"]/text()').extract()[0].strip()
# food_nickname = nicknames.split(':')[1]
# except:
# food_nickname = "無"
# url = response.meta["url"]
infoList = []
for box in response.xpath('//table[@class="table table-hover"]//tr'):
tds = box.xpath('.//td')
if len(tds) == 3:
info = {}
td_name = tds.xpath('.//text()').extract()[0]
td_unit = tds.xpath('.//text()').extract()[1]
td_value = ""
try:
td_value = td_unit + tds.xpath('.//text()').extract()[2]
info[td_name] = td_value
except:
info[td_name] = td_unit
infoList.append(info)
item['name'] = name
item['info'] = str(infoList)
# item['url'] = url
# item['nickname'] = food_nickname
yield item
print("······休眠 1 至 5 秒······")
time.sleep(random.randint(1, 5))