欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

python+selenium定時(shí)爬取丁香園的新型冠狀病毒數(shù)據(jù)并制作出類(lèi)似的地圖(部署到云服務(wù)器)

 更新時(shí)間:2020年02月09日 12:08:16   作者:七里香還是稻香  
這篇文章主要介紹了python+selenium定時(shí)爬取丁香園的新冠病毒每天的數(shù)據(jù)并制作出類(lèi)似的地圖(部署到云服務(wù)器),本文給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下

前言

硬要說(shuō)這篇文章怎么來(lái)的,那得先從那幾個(gè)吃野味的人開(kāi)始說(shuō)起…… 前天睡醒:假期還有幾天;昨天睡醒:假期還有十幾天;今天睡醒:假期還有一個(gè)月…… 每天過(guò)著幾乎和每個(gè)假期一樣的宅男生活,唯一不同的是玩手機(jī)已不再是看劇、看電影、打游戲了,而是每天都在關(guān)注著這次新冠肺炎疫情的新聞消息,真得希望這場(chǎng)戰(zhàn)“疫”快點(diǎn)結(jié)束,讓我們過(guò)上像以前一樣的生活。武漢加油!中國(guó)加油??!

本次爬取的網(wǎng)站是丁香園點(diǎn)擊跳轉(zhuǎn),相信大家平時(shí)都是看這個(gè)的吧。

一、準(zhǔn)備

python3.7

  • selenium:自動(dòng)化測(cè)試框架,直接pip install selenium安裝即可
  • pyecharts:以一切皆可配置而聞名的python封裝的js畫(huà)圖工具,其官方文檔寫(xiě)的很詳細(xì)了點(diǎn)擊跳轉(zhuǎn)。
  • 直接pip install pyecharts安裝即可,同時(shí)還需安裝以下地圖的包:

世界地圖:pip install echarts-countries-pypkg 中國(guó)地圖:pip install echarts-china-provinces-pypkg 中國(guó)城市地圖:pip install echarts-china-cities-pypkg

云服務(wù)器

二、爬取數(shù)據(jù)+畫(huà)圖

第一步、分析頁(yè)面

先用個(gè)requests模塊請(qǐng)求一下,看能不能拿到數(shù)據(jù):

import requests
url='https://ncov.dxy.cn/ncovh5/view/pneumonia_peopleapp?from=timeline&isappinstalled=0'
headers={'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.88 Safari/537.36'}
r=requests.get(url,headers=headers)
print(r.text)

發(fā)現(xiàn)數(shù)據(jù)是亂碼的并且注意到末尾處有如下字樣:

<noscript>You need to enable JavaScript to run this app.</noscript>

意思是需要執(zhí)行js代碼,百度了一下發(fā)現(xiàn)這個(gè)頁(yè)面應(yīng)該是用react.js來(lái)開(kāi)發(fā)的。限于自身技術(shù)能力,這個(gè)時(shí)候,我就只能用selenium了,它是完全模擬瀏覽器的操作,也即能執(zhí)行js代碼。

并且我需要拿到的數(shù)據(jù)并不多,也就一個(gè)頁(yè)面而已,所以耗時(shí)也可以接受。

那么我要拿哪些數(shù)據(jù)呢,如下:

  • 截至當(dāng)前時(shí)間的全國(guó)數(shù)據(jù)統(tǒng)計(jì)
  • 病毒相關(guān)描述信息
  • 全國(guó)各個(gè)省份及其城市的所有數(shù)據(jù)
  • 全世界各個(gè)地區(qū)的數(shù)據(jù)

經(jīng)過(guò)查看,發(fā)現(xiàn)這幾處需要進(jìn)行點(diǎn)擊,才能獲取到更多數(shù)據(jù)信息:

第二步、編寫(xiě)代碼

導(dǎo)入相關(guān)包:

from selenium import webdriver
from selenium.webdriver.common.action_chains import ActionChains
from selenium.webdriver.common.keys import Keys
import parsel
import time
import json
import os
import datetime
import pyecharts
from pyecharts import options as opts

定義爬取數(shù)據(jù)、保存數(shù)據(jù)的函數(shù):

def get_save_data():
 '''
 部署到云服務(wù)器上時(shí),注意:要安裝pyvirtualdisplay模塊,
 并且把下面的前5條注釋掉的代碼給去掉注釋?zhuān)龠\(yùn)行,不然會(huì)報(bào)錯(cuò)。
 '''
 #from pyvirtualdisplay import Display
 #display = Display(visible=0, size=(800, 600))
 #display.start()
 options=webdriver.ChromeOptions()
 #options.add_argument('--disable-gpu')
 #options.add_argument("--no-sandbox")
 options.add_argument('--headless') #采用無(wú)頭模式進(jìn)行爬取
 d=webdriver.Chrome(options=options)
 d.get('https://ncov.dxy.cn/ncovh5/view/pneumonia_peopleapp?from=timeline&isappinstalled=0')
 time.sleep(2)
 ActionChains(d).move_to_element(d.find_element_by_xpath('//p[@class="mapTap___1k3MH"]')).perform()
 time.sleep(2)
 d.find_element_by_xpath('//span[@class="openIconView___3hcbn"]').click()
 time.sleep(2)
 for i in range(3):
 mores=d.find_elements_by_xpath('//div[@class="areaBox___3jZkr"]')[1].find_elements_by_xpath('./div')[3:-1]
 ActionChains(d).move_to_element(d.find_element_by_xpath('//div[@class="rumorTabWrap___2kiW4"]/p')).perform()
 mores[i].click()
 time.sleep(2)
 response=parsel.Selector(d.page_source)
 china=response.xpath('//div[@class="areaBox___3jZkr"]')[0]
 world=response.xpath('//div[@class="areaBox___3jZkr"]')[1]

 # 下面是病毒相關(guān)描述信息的獲取與處理
 content=response.xpath('//div[@class="mapTop___2VZCl"]/div[1]//text()').getall()
 s=''
 for i,j in enumerate(content):
 s=s+j
 if (i+1)%2 == 0:
 s=s+'\n'
 if j in ['確診','疑似','重癥','死亡','治愈']:
 s=s+'\n'
 now=s.strip()
 msg=response.xpath('//div[@class="mapTop___2VZCl"]/div//text()').getall()
 s=''
 for i in msg:
 if i not in now:
 s=s+i+'\n'
 msg=s.strip()
 content=msg+'\n\n'+now

 # 下面是全國(guó)數(shù)據(jù)的獲取
 china_data=[]
 for div_list in china.xpath('./div')[2:-1]:
 flag=0
 city_list=[]
 for div in div_list.xpath('./div'):
 if flag == 0:
 if div.xpath('./p[1]/text()').get() is not None:
 item={}
 item['省份']=div.xpath('./p[1]/text()').get()
 item['確診']=div.xpath('./p[2]/text()').get() if div.xpath('./p[2]/text()').get() is not None else '0'
 item['死亡']=div.xpath('./p[3]/text()').get() if div.xpath('./p[3]/text()').get() is not None else '0'
 item['治愈']=div.xpath('./p[4]/text()').get() if div.xpath('./p[4]/text()').get() is not None else '0'
 flag=1
 else:
 if div.xpath('./p[1]/span/text()').get() is not None:
 temp={}
 temp['城市']=div.xpath('./p[1]/span/text()').get()
 temp['確診']=div.xpath('./p[2]/text()').get() if div.xpath('./p[2]/text()').get() is not None else '0'
 temp['死亡']=div.xpath('./p[3]/text()').get() if div.xpath('./p[3]/text()').get() is not None else '0'
 temp['治愈']=div.xpath('./p[4]/text()').get() if div.xpath('./p[4]/text()').get() is not None else '0'
 city_list.append(temp)
 item.update({'city_list':city_list})
 china_data.append(item)

 # 下面是全球數(shù)據(jù)的獲取
 world_data=[]
 for div_list in world.xpath('./div')[2:-1]:
 flag=0
 country_list=[]
 for div in div_list.xpath('./div'):
 if flag == 0:
 if div.xpath('./p[1]/text()').get() is not None:
 item={}
 item['地區(qū)']=div.xpath('./p[1]/text()').get()
 item['確診']=div.xpath('./p[2]/text()').get() if div.xpath('./p[2]/text()').get() is not None else '0'
 item['死亡']=div.xpath('./p[3]/text()').get() if div.xpath('./p[3]/text()').get() is not None else '0'
 item['治愈']=div.xpath('./p[4]/text()').get() if div.xpath('./p[4]/text()').get() is not None else '0'
 flag=1
 else:
 if div.xpath('./p[1]/span/text()').get() is not None:
 temp={}
 temp['國(guó)家']=div.xpath('./p[1]/span/text()').get()
 temp['確診']=div.xpath('./p[2]/text()').get() if div.xpath('./p[2]/text()').get() is not None else '0'
 temp['死亡']=div.xpath('./p[3]/text()').get() if div.xpath('./p[3]/text()').get() is not None else '0'
 temp['治愈']=div.xpath('./p[4]/text()').get() if div.xpath('./p[4]/text()').get() is not None else '0'
 country_list.append(temp)
 item.update({'country_list':country_list})
 world_data.append(item)
 d.quit()

 # 下面是保存數(shù)據(jù)的操作
 if not os.path.exists('./json'):
 os.makedirs('./json')
 if not os.path.exists('./txt'):
 os.makedirs('./txt')
 now_time=datetime.datetime.now().strftime("%Y-%m-%d") #獲取當(dāng)前日期
 index=list(range(len(china_data)))
 data=dict(zip(index,china_data))
 json_str = json.dumps(data, indent=4,ensure_ascii=False)
 with open(f'./json/{now_time}.json', 'w', encoding='utf-8') as f:
 f.write(json_str)
 index=list(range(len(world_data)))
 data=dict(zip(index,world_data))
 json_str = json.dumps(data, indent=4,ensure_ascii=False)
 with open(f'{now_time}.json', 'w', encoding='utf-8') as f:
 f.write(json_str)
 with open(f'./txt/{now_time}.txt', 'w', encoding='utf-8') as f:
 f.write(content)

定義畫(huà)地圖的函數(shù),輸出是一個(gè)html文件:

def get_html():
 # 首先是加載爬取到的數(shù)據(jù)
 json_files=os.listdir('./json')
 json_data=[]
 date=[]
 for i in json_files:
 with open(f'./json/{i}','r',encoding='utf-8') as f:
 date.append(i.split('.')[0])
 temp=json.load(f)
 json_data.append(list(temp.values()))
 txt_files=os.listdir('./txt') 
 content_list=[]
 for i in txt_files:
 with open(f'./txt/{i}','r',encoding='utf-8') as f:
 content_list.append(f.read())
 # 下面開(kāi)始畫(huà)圖
 t=pyecharts.charts.Timeline(init_opts=opts.InitOpts(width='1400px',height='1400px',page_title='武漢加油!中國(guó)加油??!'))
 for s,(i,data) in enumerate(zip(date,json_data)):
 value=[] # 儲(chǔ)存確診人數(shù)
 attr=[] # 儲(chǔ)存城市名字
 for each in data:
 attr.append(each['省份'])
 value.append(int(each['確診']))
 map0 = (
 pyecharts.charts.Map()
 .add(
 series_name='該省份確診數(shù)',data_pair=list(zip(attr,value)),maptype='china',is_map_symbol_show=True,zoom=1.1
 )
 .set_global_opts(title_opts=opts.TitleOpts(title="武漢加油!中國(guó)加油?。?, # 標(biāo)題
 subtitle=content_list[s], # 副標(biāo)題
 title_textstyle_opts=opts.TextStyleOpts(color='red',font_size=30), # 標(biāo)題文字
 subtitle_textstyle_opts=opts.TextStyleOpts(color='black',font_size=20),item_gap=20), # 副標(biāo)題文字
 visualmap_opts=opts.VisualMapOpts(pieces=[{"max": 9, "min": 1,'label':'1-9','color':'#FFEBCD'},
 {"max": 99, "min": 10,'label':'10-99','color':'#F5DEB3'},
 {"max": 499, "min": 100,'label':'100-499','color':'#F4A460'},
 {"max": 999, "min": 500,'label':'500-999','color':'#FA8072'},
 {"max": 9999,"min": 1000,'label':'1000-9999','color':'#ee2c0f'},
 {"min": 10000,'label':'≥10000','color':'#5B5B5B'}],
 is_piecewise=True,item_width=45,item_height=30,textstyle_opts=opts.TextStyleOpts(font_size=20))
 )
 )
 t.add(map0, "{}".format(i))
 # 將這幅圖保存為html文件
 t.render('武漢加油!中國(guó)加油??!.html')

程序入口:

if __name__ == '__main__':
 get_save_data()
 get_html()

第三步、結(jié)果展示

運(yùn)行該程序之后,會(huì)在當(dāng)前目錄下生成一個(gè)武漢加油!中國(guó)加油?。?html的文件,打開(kāi)之后如下:

ps:因?yàn)橹荒苌蟼鲌D片,所以我就將html轉(zhuǎn)為圖片了,html是動(dòng)態(tài)的,有時(shí)間軸可以拖動(dòng),由于昨天才剛開(kāi)始爬數(shù)據(jù),所以只有兩天的數(shù)據(jù)。下面附上轉(zhuǎn)圖片的代碼:

ps:又因?yàn)檫@個(gè)Timeline時(shí)間線(xiàn)輪播多圖,配置不了背景顏色,發(fā)現(xiàn)生成的圖片放大看變成黑色背景的,于是研究了一下源碼,自己修改了一下js那塊的代碼,然后就生成可以設(shè)置背景顏色的圖片了

from selenium import webdriver
import base64
import os
options=webdriver.ChromeOptions()
options.add_argument('--headless') #采用無(wú)頭模式進(jìn)行爬取
d=webdriver.Chrome(options=options)
url='file://'+os.path.abspath('武漢加油!中國(guó)加油?。?html')
d.get(url)
def decode_base64(data: str) -> bytes:
 """Decode base64, padding being optional.

 :param data: Base64 data as an ASCII byte string
 :returns: The decoded byte string.
 """
 missing_padding = len(data) % 4
 if missing_padding != 0:
 data += "=" * (4 - missing_padding)
 return base64.decodebytes(data.encode("utf-8"))
def save_as_png(image_data: bytes, output_name: str):
 with open(output_name, "wb") as f:
 f.write(image_data)
js = """
 var ele = document.querySelector('div[_echarts_instance_]');
 var mychart = echarts.getInstanceByDom(ele);
 return mychart.getDataURL({
 type: 'png',
 pixelRatio: 2,
 backgroundColor:'#FFFFFF',
 excludeComponents: ['toolbox']
 });
"""
content=d.execute_script(js)
content_array = content.split(",")
image_data = decode_base64(content_array[1])
save_as_png(image_data, '武漢加油!中國(guó)加油??!.png')
d.quit()

三、部署到云服務(wù)器

1.定時(shí)運(yùn)行獲取數(shù)據(jù)

首先將爬取數(shù)據(jù)的函數(shù),即get_save_data()單獨(dú)放到一個(gè)py文件中(我命名為:2019-nCoV.py)。然后修改定時(shí)任務(wù)/etc/crontab文件,如下:

2.通過(guò)微信獲取地圖(html文件)

把畫(huà)地圖的函數(shù),即get_html()添加到個(gè)人微信機(jī)器人當(dāng)中,然后設(shè)置特定判斷條件,在手機(jī)微信上向文件傳輸助手發(fā)送設(shè)定好的指令,執(zhí)行g(shù)et_html()函數(shù),然后把執(zhí)行函數(shù)后生成的html文件發(fā)給文件傳輸助手,從而獲取到當(dāng)前的疫情地圖。

個(gè)人微信機(jī)器人的代碼我就不再展示了,可以看我之前的文章:python實(shí)現(xiàn)微信自動(dòng)回復(fù)機(jī)器人

特定判斷的語(yǔ)句如下:

if '2019' == msg['Text']:
 get_html()
 itchat.send('@fil@%s'%'武漢加油!中國(guó)加油!!.html',toUserName='filehelper')

同時(shí),也可以把剛剛的獲取數(shù)據(jù)的函數(shù)一起添加進(jìn)去的,然后同樣通過(guò)發(fā)送特定指令運(yùn)行函數(shù),而獲取數(shù)據(jù),我這里不加進(jìn)去呢,是因?yàn)槲乙O(shè)置個(gè)定時(shí)任務(wù),定時(shí)獲取就行了;并且我也可以通過(guò)給文件傳輸助手發(fā)送shell命令,執(zhí)行py文件。

把下面的代碼加進(jìn)個(gè)人微信機(jī)器人py文件里就行了。

import subprocess
def cmd(command):
 output=subprocess.getoutput(command)
 return output

并給出我的特定判斷語(yǔ)句:

if 'cmd' in msg['Text']:
 output=cmd(msg['Text'][3:])
 if output != '':
 itchat.send(output, toUserName='filehelper')

四、運(yùn)行展示

如上圖所示:我先是執(zhí)行了爬取數(shù)據(jù)的函數(shù),即我調(diào)用了云服務(wù)器上的定時(shí)爬取數(shù)據(jù)的py文件,然后再輸入指令獲取當(dāng)前的疫情地圖,打開(kāi)后像上面的疫情地圖一樣。

寫(xiě)在最后

世界的疫情地圖我沒(méi)有畫(huà),是因?yàn)閜yecharts的世界地圖各個(gè)地區(qū)是用英文命名的,跟獲取到的地區(qū)匹配不上,其實(shí)可以加個(gè)中文轉(zhuǎn)英文給它,那就可以了,我懶的弄了,有興趣的朋友可以試一試哦

一開(kāi)始,我只是在那些爬蟲(chóng)微信群上看到:今天這誰(shuí)在爬丁香園的數(shù)據(jù),過(guò)幾天又看到那誰(shuí)又在爬丁香園的數(shù)據(jù),而且還提出各種問(wèn)題來(lái)討論。我實(shí)在是看不下去了,于是就有了這一篇文章(反正在家閑著也是閑著)

然后呢,今天學(xué)校發(fā)通知說(shuō)校外的大四學(xué)生也可以申請(qǐng)vpn,然后在家就可以查看和下載知網(wǎng)的文獻(xiàn)了。準(zhǔn)備畢業(yè)的我突然驚了,我的論文還未開(kāi)始寫(xiě)呢!看來(lái)是時(shí)候了……

其實(shí)我是想回學(xué)校再寫(xiě)的,但是這次的新冠肺炎疫情來(lái)勢(shì)兇猛,真的希望快點(diǎn)好起來(lái)啊~

武漢加油!中國(guó)加油??!

總結(jié)

以上所述是小編給大家介紹的python+selenium定時(shí)爬取丁香園的新冠病毒每天的數(shù)據(jù)并制作出類(lèi)似的地圖(部署到云服務(wù)器),希望對(duì)大家有所幫助!

相關(guān)文章

  • python生成隨機(jī)驗(yàn)證碼(中文驗(yàn)證碼)示例

    python生成隨機(jī)驗(yàn)證碼(中文驗(yàn)證碼)示例

    這篇文章主要介紹了python生成中文隨機(jī)驗(yàn)證碼示例,需要的朋友可以參考下
    2014-04-04
  • 如何使用Python生成Hilbert矩陣

    如何使用Python生成Hilbert矩陣

    這篇文章主要介紹了如何使用Python生成Hilbert矩陣,文章圍繞主題展開(kāi)詳細(xì)的內(nèi)容介紹,具有一定的參考價(jià)值,需要的小伙伴可以參考一下
    2022-09-09
  • python實(shí)現(xiàn)釘釘機(jī)器人自動(dòng)打卡天天早下班

    python實(shí)現(xiàn)釘釘機(jī)器人自動(dòng)打卡天天早下班

    這篇文章主要為大家介紹了python實(shí)現(xiàn)釘釘機(jī)器人自動(dòng)打卡天天下早班實(shí)例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-06-06
  • 用Python設(shè)計(jì)一個(gè)經(jīng)典小游戲

    用Python設(shè)計(jì)一個(gè)經(jīng)典小游戲

    本篇文章主要介紹如何用Python設(shè)計(jì)一個(gè)經(jīng)典小游戲:猜大小。具有很好的參考價(jià)值。下面跟著小編一起來(lái)看下吧
    2017-05-05
  • Python中Django 后臺(tái)自定義表單控件

    Python中Django 后臺(tái)自定義表單控件

    本篇文章主要介紹了Python中Django 后臺(tái)自定義表單控件,其實(shí) django 已經(jīng)為我們提供了一些可用的表單控件,比如:多選框、單選按鈕等,有興趣的開(kāi)業(yè)了解一下。
    2017-03-03
  • python里的條件語(yǔ)句和循環(huán)語(yǔ)句你了解多少

    python里的條件語(yǔ)句和循環(huán)語(yǔ)句你了解多少

    這篇文章主要為大家詳細(xì)介紹了python的條件語(yǔ)句和循環(huán)語(yǔ)句,使用數(shù)據(jù)庫(kù),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-02-02
  • Python異常與錯(cuò)誤處理詳細(xì)講解

    Python異常與錯(cuò)誤處理詳細(xì)講解

    這篇文章主要介紹了Python異常與錯(cuò)誤處理,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)吧
    2022-12-12
  • Form表單及django的form表單的補(bǔ)充

    Form表單及django的form表單的補(bǔ)充

    這篇文章主要介紹了Form表單及django的form表單的補(bǔ)充,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2019-07-07
  • Python3.4 splinter(模擬填寫(xiě)表單)使用方法

    Python3.4 splinter(模擬填寫(xiě)表單)使用方法

    今天小編就為大家分享一篇Python3.4 splinter(模擬填寫(xiě)表單)使用方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2018-10-10
  • python使用for循環(huán)和海龜繪圖實(shí)現(xiàn)漂亮螺旋線(xiàn)

    python使用for循環(huán)和海龜繪圖實(shí)現(xiàn)漂亮螺旋線(xiàn)

    這篇文章主要為大家介紹了python使用for循環(huán)和海龜繪圖實(shí)現(xiàn)漂亮螺旋線(xiàn)實(shí)現(xiàn)示例,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-06-06

最新評(píng)論