佳木斯湛栽影视文化发展公司

主頁 > 知識庫 > Python爬蟲爬取全球疫情數(shù)據(jù)并存儲到mysql數(shù)據(jù)庫的步驟

Python爬蟲爬取全球疫情數(shù)據(jù)并存儲到mysql數(shù)據(jù)庫的步驟

熱門標簽:百度AI接口 客戶服務 Win7旗艦版 語音系統(tǒng) 電話運營中心 企業(yè)做大做強 硅谷的囚徒呼叫中心 呼叫中心市場需求

思路:使用Python爬蟲對騰訊疫情網(wǎng)站世界疫情數(shù)據(jù)進行爬取,封裝成一個函數(shù)返回一個

     字典數(shù)據(jù)格式的對象,寫另一個方法調(diào)用該函數(shù)接收返回值,和數(shù)據(jù)庫取得連接后把

     數(shù)據(jù)存儲到mysql數(shù)據(jù)庫。

一、mysql數(shù)據(jù)庫建表

CREATE TABLE world(
 id INT(11) NOT NULL AUTO_INCREMENT,
 dt DATETIME NOT NULL COMMENT '日期',
 c_name VARCHAR(35) DEFAULT NULL COMMENT '國家',
 continent VARCHAR(35) DEFAULT NULL COMMENT '所屬大洲',
 nowConfirm INT(11) DEFAULT NULL COMMENT '累計確診',
 confirm INT(11) DEFAULT NULL COMMENT '當日現(xiàn)存確診',
 confirmAdd INT(11) DEFAULT NULL COMMENT '當日新增確診',
 suspect INT(11) DEFAULT NULL COMMENT '剩余疑似',
 heal INT(11) DEFAULT NULL COMMENT '累計治愈',
 dead INT(11) DEFAULT NULL COMMENT '累計死亡',
 confirmAddCut INT(11) DEFAULT NULL COMMENT 'confirmAddCut',
 confirmCompare INT(11) DEFAULT NULL COMMENT 'confirmCompare',
 nowConfirmCompare INT(11) DEFAULT NULL COMMENT 'nowConfirmCompare',
 healCompare INT(11) DEFAULT NULL COMMENT 'healCompare',
 deadCompare INT(11) DEFAULT NULL COMMENT 'deadCompare',
 PRIMARY KEY(id)
)ENGINE=INNODB DEFAULT CHARSET=utf8mb4;

注意建立的表,數(shù)據(jù)的名字,數(shù)據(jù)的長度,數(shù)據(jù)的類型,主鍵的定義一定要小心仔細。

這里博主出現(xiàn)了幾個小錯誤:

①數(shù)據(jù)表的主鍵不可以設(shè)置為日期,因為在之后爬取數(shù)據(jù)之后可以看到,網(wǎng)站給的數(shù)據(jù)是同一天的,

因為主鍵不可以有重復,所以相同的日期是不可以作為主鍵定義的。

②設(shè)置int類型的id作為數(shù)據(jù)表的主鍵,那么存在一個問題,在往表里插入數(shù)據(jù)的時候,id位置的數(shù)據(jù)值需要考慮,

這個方法可以解決:可以在傳值的時候把id的值設(shè)定為 0,前提是id是自增的,

這樣數(shù)據(jù)庫是可以自己處理id的,依然是從0開始自增,這樣避免了不給id傳值導致Null的異常。

③博主使用的mysql可視化工具默認在一個頁面顯示30條記錄,在右上角可以改變顯示的記錄數(shù),因為本次插入的

是185條數(shù)據(jù),所以在插入完之后如果發(fā)現(xiàn)數(shù)據(jù)不對,可以看看可視化工具是不是有什么設(shè)置導致的。

二、下面直接上代碼(爬蟲方法)

"""
獲取全球疫情數(shù)據(jù)
"""
def get_world_data():
 url='https://api.inews.qq.com/newsqa/v1/automation/foreign/country/ranklist'
 headers={'user-agent': 'WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.198 Safari/537.36'}
 # 創(chuàng)建會話對象
 # session = requests.session()
 # 請求接口
 # result = session.get('https://api.inews.qq.com/newsqa/v1/automation/foreign/country/ranklist')
 # 打印結(jié)果
 # print(result.text)
 res = requests.get(url, headers=headers)
 # print(res.text)
 response_data_0 = json.loads(res.text.replace('jQuery34102848205531413024_1584924641755(', '')[:-1]) #轉(zhuǎn)化json對象
 # print(response_data_0.keys())
 # print(response_data_0)
 response_data_1=response_data_0['data']
 # print(response_data_1)
 # print(response_data_1[0].keys())
 # data = jsonpath.jsonpath(resJson_1, '$.data.*')
 # print(resJson_1.keys())
 # for d in data:
 # res = '日期:' + d['date'] + '--' + d['continent'] + '--' + d['name'] + '--' + '新增確診:' + str(
 # d['confirmAdd']) + '累計確診:' + str(d['confirm']) + '治愈:' + str(d['heal']) + '死亡:' + str(d['dead'])
 # file = r'C:/Users/Administrator/Desktop/world_data.txt'
 # with open(file, 'w+', encoding='utf-8') as f:
 # f.write(res + '\n') # 加\n換行顯示
 # f.close()
 world={}
 for i in response_data_1:
 temp=i['y']+'.'+i['date']
 tup = time.strptime(temp, '%Y.%m.%d')
 dt = time.strftime('%Y-%m-%d', tup) # 改變時間格式,插入數(shù)據(jù)庫 日期
 # print(ds)
 c_name=i['name'] #國家
 continent=i['continent'] #所屬大洲
 nowConfirm=i['nowConfirm'] #現(xiàn)有確診
 confirm=i['confirm'] #累計確診
 confirmAdd=i['confirmAdd'] #新增確診
 suspect=i['suspect'] #現(xiàn)有疑似
 heal=i['heal'] #累計治愈
 dead=i['dead'] #累計死亡
 confirmAddCut=i['confirmAddCut']
 confirmCompare=i['confirmCompare']
 nowConfirmCompare=i['nowConfirmCompare']
 healCompare=i['healCompare']
 deadCompare=i['deadCompare']
 world[c_name] = {'dt':dt ,
  'continent': continent,
  'nowConfirm': nowConfirm,
  'confirm': confirm,
  'confirmAdd': confirmAdd,
  'suspect': suspect,
  'heal': heal,
  'dead': dead,
  'confirmAddCut': confirmAddCut,
  'confirmCompare': confirmCompare,
  'nowConfirmCompare': nowConfirmCompare,
  'healCompare': healCompare,
  'deadCompare': deadCompare,
  }
 return world

三、插入數(shù)據(jù)庫

def insert_world():
 """
 更新 world 表
 :return:
 """
 cursor = None
 conn = None
 try:
 dic = get_world_data()
 print(dic)
 conn, cursor = get_conn()
 sql = "insert into world values(%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s)"
 sql_query = 'select %s=(select dt from world order by id desc limit 1)' #對比當前最大時間戳
 cursor.execute(sql_query,dic['美國']['dt'])
 if not cursor.fetchone()[0]:
 print(f"{time.asctime()}開始插入世界數(shù)據(jù)")
 for k, v in dic.items(): # item 格式 {'2021-01-13': {'confirm': 41, 'suspect': 0, 'heal': 0, 'dead': 1}
 cursor.execute(sql, [0,v.get('dt'), k, v.get("continent"), v.get("nowConfirm"),
  v.get("confirm"), v.get("confirmAdd"),v.get("suspect"),v.get("heal"), v.get("dead")
  , v.get("confirmAddCut"), v.get("confirmCompare"), v.get("nowConfirmCompare"), v.get("healCompare"),
 v.get("deadCompare")])
 conn.commit() # 提交事務
 print(f"{time.asctime()}插入世界數(shù)據(jù)完畢")
 else:
 print(f"{time.asctime()}世界數(shù)據(jù)已是最新數(shù)據(jù)!")
 except:
 traceback.print_exc()
 finally:
 close_conn(conn, cursor)

總結(jié)一下在完成這兩個方法的過程中遇到的問題,首先是最基礎(chǔ)的問題,數(shù)據(jù)的類型和格式的轉(zhuǎn)換,這里主要是指json字符串和

Python里對應的數(shù)據(jù)對象(list和字典)。

(1)一般來講對我們而言,需要抓取的是某個網(wǎng)站或者某個應用的內(nèi)容,提取有用的價值。內(nèi)容一般分為三部分,

結(jié)構(gòu)化的數(shù)據(jù)、半結(jié)構(gòu)化的數(shù)據(jù)和非機構(gòu)化數(shù)據(jù)。

1.結(jié)構(gòu)化數(shù)據(jù):
       可以用統(tǒng)一的結(jié)構(gòu)加以表示的數(shù)據(jù)??梢允褂藐P(guān)系型數(shù)據(jù)庫表示和存儲,表現(xiàn)為二維形式的數(shù)據(jù),一般特點是:數(shù)據(jù)以行為單位,

  一行數(shù)據(jù)表示一個實體的信息,每一行的數(shù)據(jù)的屬性是相同的。
2.半結(jié)構(gòu)化數(shù)據(jù):
       結(jié)構(gòu)化數(shù)據(jù)的一種形式,并不符合關(guān)系型數(shù)據(jù)庫或其他數(shù)據(jù)表的形式關(guān)聯(lián)起來的數(shù)據(jù)模型結(jié)構(gòu),但包含相關(guān)標記,

  用來分隔語義元素以及對記錄和字段進行分層。因此他也被成為自描述的結(jié)構(gòu)。常見的半結(jié)構(gòu)數(shù)據(jù)有:html,xml和json等、

  實際上是以樹或者圖的結(jié)構(gòu)來存儲的。
       對于半結(jié)構(gòu)化數(shù)據(jù),節(jié)點中屬性的順序是不重要的,不同的半結(jié)構(gòu)化數(shù)據(jù)的屬性的個數(shù)是不一樣的。這樣的數(shù)據(jù)格式,

  可以自由的表達很多有用的信息,

  包含自描述信息。所以半結(jié)構(gòu)化數(shù)據(jù)的擴展性很好,特別適合于在互聯(lián)網(wǎng)中大規(guī)模傳播。
3.非結(jié)構(gòu)化數(shù)據(jù)

  就是沒有固定的結(jié)構(gòu)。各種文檔,圖片,視頻或者音頻都屬于非結(jié)構(gòu)化數(shù)據(jù)。對于這類數(shù)據(jù),我們一般直接整體進行存儲,而且一般存儲為二進制形式。

原文鏈接:www.jb51.net/article/208448.htm

json數(shù)據(jù)      

 json(JavaScript Object Notation,JS對象標記)是一種輕量級的數(shù)據(jù)交換格式。

基于ECMAScript(w3c制定的JS規(guī)范)的一個子集,采用完全獨立于編程語言的文本格式來存儲和表示數(shù)據(jù)。

簡潔和清晰的層次結(jié)構(gòu)使得JSON成為理想的數(shù)據(jù)交換語言。

       特點:易于閱讀、易于機器生成、有效提升網(wǎng)絡速度。       

JSON語法規(guī)則:

在JS語言中,一切都是對象。因此,任何支持的類型都可以通過json來表示。

例如字符串、數(shù)字,對象,數(shù)組。
Js中對象和數(shù)組是比較特殊并且常用的兩種類型:
       1、對象表示為鍵值對{name:'zhangsan',age:'7'}
       2、數(shù)據(jù)有逗號分隔[1,2,3,4,5]
       3、花括號保存對象
       4、方括號保存數(shù)組。
js的對象就相當于python中的字典
js的數(shù)組就相當于Python中的列表
       因為json用來存儲js的對象或者數(shù)組,所以在Python中我們可以將json轉(zhuǎn)化為list或者dict。

解析json的包json:
       json.dumps(python的list或者dict)---->(返回值)---->json字符串。
       json.loads(json字符串)------>(返回值)----->python的list或者dict.

       json.dump(list/dict,fp)—>list,或者字典保存到json文件中。
       json.load(fp)—>list/dict:從json文件中讀出json數(shù)據(jù)。

       json鍵值對是用來保存js對象的一種方式,和js對象的寫法頁大同小異,比如:
  {“firstName”:“Json”,“Class”:“aid1111”}等價于下面這條js語句:{firstName:“Json”,Class:“aid1111”}。
       很多人搞不清楚json和js對象的關(guān)系,甚至誰是誰都不清楚。其實可以這么理解:

  【JSON是JS對象的字符串表達式,他使用文本形式表示一個JS對象的信息,本質(zhì)是一個字符串。】
        如var obj = {a:“hello”,b:“World”}這是一個js對象。注意,鍵名也是可以用引號包裹的var json = ' {“a”:“hello”,“b”:“World”}'這是一個json字符串,本質(zhì)上是一個字符串。
       JSON作為數(shù)據(jù)包格式傳輸?shù)臅r候具有更高的效率,這是因為JSON不想xml那樣具有嚴格的閉合標簽,這就讓有效數(shù)據(jù)量與總數(shù)據(jù)包比大大提升,從而減少同等數(shù)據(jù)流量的情況下,網(wǎng)絡的傳輸?shù)膲毫Υ蟠鬁p低。

之前寫過一篇關(guān)于爬取中國疫情數(shù)據(jù)的博客文章,那里爬取的每日疫情數(shù)據(jù)和全球爬取的疫情數(shù)據(jù)格式有一點點不同:

這是中國的疫情數(shù)據(jù),注意箭頭指的地方,這里的data對應的key是字典

這是全球疫情,注意這里data對應的是list

數(shù)據(jù)的格式非常重要,因為在后續(xù)需要把網(wǎng)頁爬取的數(shù)據(jù)接受之后,還要把數(shù)據(jù)導入數(shù)據(jù)庫,所以中間數(shù)據(jù)的格式必須清楚,

比如list類型的可以通過下標去訪問,而字典只可以通過name來訪問,字典是不提供索引的,所以不可以通過下標訪問。還

有就是數(shù)據(jù)庫里的日期格式一定要注意轉(zhuǎn)換再插入。

四、總結(jié)一下爬取數(shù)據(jù)的步驟:

(1)首先需要導入需要的包:

import requests
import pymysql
import time
import json
import traceback

(2)通過request向被爬取網(wǎng)站的url發(fā)起一個請求(如果網(wǎng)站有反爬取手段,需要在請求里加上headers)
獲取headers:

到指定網(wǎng)站,瀏覽器按F12,之后在網(wǎng)絡那一個選項里可以看到。

 (3)獲取和解析數(shù)據(jù)

 url='https://api.inews.qq.com/newsqa/v1/automation/foreign/country/ranklist'
 headers={'user-agent': 'WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.198 Safari/537.36'}
 
 res = requests.get(url, headers=headers)
 # print(res.text)
 response_data_0 = json.loads(res.text.replace('jQuery34102848205531413024_1584924641755(', '')[:-1]) #轉(zhuǎn)化json對象

這里進行了第一步解析,通過json.loads( ) 方法把從網(wǎng)頁獲取的json字符串數(shù)據(jù)轉(zhuǎn)化成Python對應的list或者字典。

如果第一步解析之后data對應的value不是list,那么可以進行第二次解析,本次操作中,世界疫情數(shù)據(jù)的data對

應的數(shù)據(jù)是一個list,所以也就不需要進行第二次轉(zhuǎn)化,可以直接通過list的下標去訪問。

數(shù)據(jù)轉(zhuǎn)化是必要的,在網(wǎng)絡中json字符串傳遞小巧安全速度快,但是我們讀取數(shù)據(jù),如果直接對字符串進行操作

會非常不方便,所以我們需要解析json字符串,也就是通過json.loads()方法把字符串轉(zhuǎn)化成Python對應的list或

者字典對象,這樣我們訪問操作這些數(shù)據(jù)會變得簡單。

以上就是Python爬蟲爬取全球疫情數(shù)據(jù)并存儲到mysql數(shù)據(jù)庫的步驟的詳細內(nèi)容,更多關(guān)于python 爬取疫情數(shù)據(jù)存儲到mysql的資料請關(guān)注腳本之家其它相關(guān)文章!

您可能感興趣的文章:
  • 教你如何使用Python快速爬取需要的數(shù)據(jù)
  • python爬取豆瓣電影TOP250數(shù)據(jù)
  • python爬取鏈家二手房的數(shù)據(jù)
  • Python手拉手教你爬取貝殼房源數(shù)據(jù)的實戰(zhàn)教程
  • Python數(shù)據(jù)分析之Python和Selenium爬取BOSS直聘崗位
  • python爬蟲之爬取谷歌趨勢數(shù)據(jù)
  • python selenium實現(xiàn)智聯(lián)招聘數(shù)據(jù)爬取
  • python爬蟲之教你如何爬取地理數(shù)據(jù)
  • Python爬取騰訊疫情實時數(shù)據(jù)并存儲到mysql數(shù)據(jù)庫的示例代碼
  • Python爬蟲之自動爬取某車之家各車銷售數(shù)據(jù)

標簽:山西 崇左 安康 海南 長沙 山西 喀什 濟南

巨人網(wǎng)絡通訊聲明:本文標題《Python爬蟲爬取全球疫情數(shù)據(jù)并存儲到mysql數(shù)據(jù)庫的步驟》,本文關(guān)鍵詞  ;如發(fā)現(xiàn)本文內(nèi)容存在版權(quán)問題,煩請?zhí)峁┫嚓P(guān)信息告之我們,我們將及時溝通與處理。本站內(nèi)容系統(tǒng)采集于網(wǎng)絡,涉及言論、版權(quán)與本站無關(guān)。
  • 相關(guān)文章
  • 收縮
    • 微信客服
    • 微信二維碼
    • 電話咨詢

    • 400-1100-266
    商丘市| 江永县| 阳信县| 南投县| 太白县| 天津市| 伽师县| 佳木斯市| 称多县| 贡觉县| 昌吉市| 广东省| 蒙城县| 新和县| 博白县| 新巴尔虎右旗| 卢氏县| 贵南县| 德惠市| 百色市| 安塞县| 酒泉市| 安康市| 广南县| 亚东县| 子长县| 临沧市| 永靖县| 工布江达县| 雅安市| 宁陕县| 宿州市| 巴彦淖尔市| 双江| 禄丰县| 临沭县| 花莲县| 诸城市| 高州市| 马边| 手机|