python爬蟲——氣象數據爬取

一、導入庫與全局配置

python

運行

import json
import datetime
import time
import requests
from sqlalchemy import create_engine
import csv
import pandas as pd

作用

  • 引入數據解析、網絡請求、時間處理、數據庫操作等所需庫。
  • requests:發送 HTTP 請求獲取網頁數據。
  • sqlalchemy:連接和操作 MySQL 數據庫。
  • pandas:處理 CSV 文件和數據清洗。

潛在問題

  • 未處理requests的超時(可能導致程序卡死)。
  • 數據庫密碼直接寫死在代碼中(存在安全風險)。

二、核心爬取函數?scraw(code)

python

運行

def scraw(code):url = f'http://www.nmc.cn/rest/weather?stationid={code}&_=1675259309000'response = requests.get(url, headers=headers)try:data = json.loads(response.text)info = data['data']passed = data['data']['passedchart']real = data['data']['real']tempchart = data['data']['tempchart']predict = data['data']['predict']['detail']# 解析24小時天氣數據并寫入CSVfor i in passed:csv.writer(csv_obj).writerow([names[inx], ...])# 解析實時天氣數據并寫入CSVcsv.writer(csv_obj2).writerow([names[inx], ...])# 解析7天溫度數據并寫入CSVfor i in tempchart:csv.writer(csv_obj3).writerow([names[inx], ...])# 解析預報數據并寫入CSVfor i in predict:csv.writer(csv_obj4).writerow([names[inx], ...])except:print(f'{code}爬取失敗')

功能拆解

  1. URL 構造

    • 拼接城市代碼(stationid)和時間戳參數(_),可能用于防止緩存。
    • 問題:時間戳硬編碼(1675259309000),未動態生成,可能導致請求失效。
  2. 數據解析

    • 通過json.loads()解析 JSON 響應,提取passedchart(歷史數據)、real(實時數據)等字段。
    • 風險:假設 JSON 結構固定,若網站接口變更會導致解析失敗(需添加容錯處理)。
  3. CSV 寫入

    • 循環寫入不同類型數據到 4 個 CSV 文件(data24h.csvdataday.csv等)。
    • 問題names[inx]依賴全局變量inx,多線程環境下可能引發線程安全問題。

三、降雨量爬取函數?scraw_rain24h()?&?scraw_rain1h()

python

運行

def scraw_rain24h():url = f'http://www.nmc.cn/rest/real/rain/hour24/{date}?_={times}'csv_obj5 = open('csv/rain24h.csv', 'w', ...)response = requests.get(url, headers=headers)data = json.loads(response.text)raindata = data['data']['data']for i in raindata:csv.writer(csv_obj5).writerow([i[0]+i[1], i[5]])csv_obj5.close()def scraw_rain1h():# 邏輯與scraw_rain24h()類似,僅URL和CSV文件不同

關鍵細節

  • URL 參數date由主程序生成(格式為YYYYMMDD08),times為當前時間戳(動態生成)。
  • 數據結構:降雨量數據通過i[0]+i[1]拼接城市名(假設i[0]為省,i[1]為市),i[5]為降雨量。
  • 問題:未處理城市名重復或異常數據(如i[0]i[1]為空)。

四、數據庫存儲函數?save()

python

運行

def save():DB_STRING = 'mysql+pymysql://root:mysql@127.0.0.1:3306/tianqi'engine = create_engine(DB_STRING)# 讀取CSV文件df = pd.read_csv("csv/data24h.csv")df2 = pd.read_csv("csv/dataday.csv")# ... 讀取其他CSV文件# 數據清洗df = df.drop('24h降雨量', axis=1)df2 = df2[df2['體感溫度'] != 9999]df3 = df3[df3['最高溫度'] != 9999]# 寫入數據庫df.to_sql('24h', con=engine, if_exists='replace', index=False)# ... 寫入其他DataFrame

功能說明

  1. 數據庫連接

    • 使用 SQLAlchemy 創建數據庫引擎,連接本地 MySQL 的tianqi數據庫。
    • 風險:密碼mysql硬編碼,需通過環境變量或配置文件管理。
  2. 數據清洗

    • 刪除無效列(如24h降雨量)和值為9999的行(假設9999為錯誤值)。
    • 問題:清洗邏輯分散,未統一處理(如其他 CSV 文件可能也存在無效值)。
  3. 數據寫入

    • 使用to_sql批量寫入,if_exists='replace'會覆蓋表數據(可能導致歷史數據丟失)。

五、主程序邏輯(if __name__ == '__main__'

python

運行

if __name__ == '__main__':df = pd.read_csv('csv/citycode.csv')codes = df.code.tolist()names = df.城市.tolist()date = time.strftime('%Y%m%d', time.gmtime()) + '08'times = int(time.time() * 1000)headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; ...)'}# 初始化CSV文件csv_obj = open('csv/data24h.csv', 'w', ...)# ... 初始化其他CSV文件for inx, i in enumerate(codes):scraw(i)print(f"{names[inx]}爬取完畢")# 關閉CSV文件csv_obj.close()# ... 關閉其他CSV文件scraw_rain24h()scraw_rain1h()save()

流程分析

  1. 準備階段

    • 讀取城市代碼表(citycode.csv),獲取codes(城市代碼)和names(城市名)。
    • 生成date(當前日期 +08,可能為北京時間時區調整)和times(毫秒級時間戳)。
  2. 爬取階段

    • 循環調用scraw(i)爬取每個城市的數據,依賴全局變量inxnames
    • 問題:未控制爬取頻率(可能觸發網站反爬機制),建議添加time.sleep()
  3. 收尾階段

    • 關閉 CSV 文件句柄(需確保在異常情況下也能關閉,建議用with語句)。
    • 爬取降雨量數據并保存到數據庫。

六、整體問題總結與改進方向

模塊問題改進建議
爬取邏輯硬編碼時間戳、未處理反爬動態生成時間戳,添加請求頭(如Referer)、限制爬取頻率
異常處理全局except捕獲,無詳細日志細化異常類型,使用logging模塊記錄錯誤信息
資源管理CSV 文件未用with語句,可能泄漏資源改用with open(...) as f管理文件
數據安全數據庫密碼硬編碼使用環境變量(如os.getenv())或配置文件
代碼可維護性全局變量耦合嚴重,邏輯分散將功能封裝為類,分離爬取、解析、存儲邏輯
擴展性難以為新城市或數據類型擴展設計可配置的爬取規則和字段映射

通過分塊優化,可顯著提升代碼的健壯性、可維護性和安全性,同時降低對目標網站的影響。

?完整代碼:

import json
import datetime
import time
import requests
from sqlalchemy import create_engine
import csv
import pandas as pddef scraw(code):# 發送 HTTP 請求,獲取網頁內容url = f'http://www.nmc.cn/rest/weather?stationid={code}&_=1675259309000'response = requests.get(url, headers=headers)try:data = json.loads(response.text)info = data['data']# 24小時天氣情況passed = data['data']['passedchart']# 一天real = data['data']['real']# 最近七天最高低溫度tempchart = data['data']['tempchart']# 預測predict = data['data']['predict']['detail']for i in passed:humidity = i['humidity']  # 相對濕度pressure = i['pressure']  # 空氣壓力rain1h = i['rain1h']  #rain24h = i['rain24h']  #temperature = i['temperature']  # 溫度windDirection = i['windDirection']windSpeed = i['windSpeed']time = i['time']tempDiff = i['tempDiff']  # 體感溫度csv.writer(csv_obj).writerow([names[inx],humidity, pressure, rain1h, rain24h, temperature, windDirection, windSpeed, time, tempDiff])csv.writer(csv_obj2).writerow([names[inx],datetime.datetime.now().date(), real['weather']['airpressure'], real['weather']['feelst'],real['weather']['humidity'], real['weather']['info'], real['weather']['rain'], real['weather']['temperature'],real['wind']['direct'], real['wind']['power'], real['wind']['speed']])for i in tempchart:time = i['time']max_temp = i['max_temp']min_temp = i['min_temp']csv.writer(csv_obj3).writerow([names[inx],time, max_temp, min_temp])for i in predict:date = i['date']temperatureday = i['day']['weather']['temperature']temperaturenight = i['night']['weather']['temperature']wind = i['day']['wind']['direct']csv.writer(csv_obj4).writerow([names[inx],date, temperatureday, temperaturenight, wind])except:print(f'{code}爬取失敗')def scraw_rain24h():url = f'http://www.nmc.cn/rest/real/rain/hour24/{date}?_={times}'csv_obj5 = open('csv/rain24h.csv', 'w', encoding="utf-8",newline='')response = requests.get(url, headers=headers)data = json.loads(response.text)print(data)raindata = data['data']['data']csv.writer(csv_obj5).writerow(["城市",'降雨量'])for i in raindata:csv.writer(csv_obj5).writerow([i[0] +i[1], i[5]])print('爬取數據完畢')csv_obj5.close()def scraw_rain1h():url = f'http://www.nmc.cn/rest/real/rain/hour1/{date}?_={times}'csv_obj6 = open('csv/rain1h.csv', 'w', encoding="utf-8", newline='')response = requests.get(url, headers=headers)data = json.loads(response.text)raindata = data['data']['data']csv.writer(csv_obj6).writerow(["城市", '降雨量'])for i in raindata:csv.writer(csv_obj6).writerow([i[0] + i[1], i[5]])print('爬取數據完畢')csv_obj6.close()def save():# 存入數據庫DB_STRING = 'mysql+pymysql://root:mysql@127.0.0.1:3306/tianqi'engine = create_engine(DB_STRING)df = pd.read_csv("csv/data24h.csv")df2 = pd.read_csv("csv/dataday.csv")df3 = pd.read_csv("csv/tempchart.csv")df4 = pd.read_csv("csv/predict.csv")df5 = pd.read_csv("csv/rain24h.csv")df6 = pd.read_csv("csv/rain1h.csv")#刪除不正常值# 刪除部分列值等于9999的行df = df.drop('24h降雨量',axis=1)df2 = df2[df2['體感溫度'] != 9999]df3 = df3[df3['最高溫度'] != 9999]df.to_sql('24h', con=engine, if_exists='replace',index=False)df2.to_sql('day', con=engine, if_exists='replace',index=False)df3.to_sql('tempchart', con=engine, if_exists='replace',index=False)df4.to_sql('predict', con=engine, if_exists='replace',index=False)df5.to_sql('rain24h', con=engine, if_exists='replace',index=False)df6.to_sql('rain1h', con=engine, if_exists='replace',index=False)print('保存數據庫完畢')if __name__ == '__main__':df = pd.read_csv('csv/citycode.csv')codes = df.code.tolist()names = df.城市.tolist()#北京# codes = [54511]# names = ['北京']date = time.strftime('%Y%m%d', time.gmtime()) +'08'times = int(time.time() * 1000)# # 設置請求頭部信息,避免被識別為爬蟲headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.3'}csv_obj = open('csv/data24h.csv', 'w', encoding="utf-8",newline='')csv_obj2 = open('csv/dataday.csv', 'w', encoding="utf-8", newline='')csv_obj3 = open('csv/tempchart.csv', 'w', encoding="utf-8", newline='')csv_obj4 = open('csv/predict.csv', 'w', encoding="utf-8", newline='')csv.writer(csv_obj).writerow(["城市","相對濕度", "氣壓", "一小時降雨量","24h降雨量", "溫度", "風向", "風速","時間",'體感溫度'])csv.writer(csv_obj2).writerow(["城市","日期","氣壓", '體感溫度',"相對濕度","天氣情況","一小時降雨量","溫度", "風向", "風強度","風速"])csv.writer(csv_obj3).writerow(["城市","日期","最高溫度", '最低溫度'])csv.writer(csv_obj4).writerow(["城市","日期","白天溫度", '夜晚溫度',"風向"])for inx,i in enumerate(codes):scraw(i)print(f"{names[inx]}爬取完畢")csv_obj.close()csv_obj2.close()csv_obj3.close()csv_obj4.close()scraw_rain24h()scraw_rain1h()save()

?

import csv
import json
import requests
# 設置請求頭部信息,避免被識別為爬蟲headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.3'}# 發送 HTTP 請求,獲取網頁內容url = 'http://www.nmc.cn/rest/province/all?_=1678112903659'
response = requests.get(url, headers=headers)
data = json.loads(response.text)
csv_obj = open('allcsv/citycode.csv', 'w', encoding="utf-8", newline='')
csv.writer(csv_obj).writerow(['城市','code'])
for i in data:code = i['code']url = f'http://www.nmc.cn/rest/province/{code}?_=1677854971362'response = requests.get(url, headers=headers)data = json.loads(response.text)for x in data:csv.writer(csv_obj).writerow([x['city'], x['code']])csv_obj.close()

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/pingmian/84273.shtml
繁體地址,請注明出處:http://hk.pswp.cn/pingmian/84273.shtml
英文地址,請注明出處:http://en.pswp.cn/pingmian/84273.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Python爬蟲(三):BeautifulSoup庫

1. BeautifulSoup是什么? BeautifulSoup 是一個 Python 庫,專門用來解析 HTML 或 XML 文件,方便我們提取數據。它能把網頁源代碼轉換成樹形結構,讓我們可以輕松查找、修改內容,并自動處理編碼問題(如 Unic…

AI電銷機器人智能的發展趨勢是什么?

AI電銷機器人智能的發展趨勢是什么?電銷機器人智能的發展前景怎么樣?隨著互聯網技術的不斷發展,AI電銷機器人智能已經成為了許多企業實現銷售數字化轉型的重要工具,我們一起來看看。 AI電銷機器人正突破傳統語音機械應答的邊界&a…

C++ 求圓面積的程序(Program to find area of a circle)

給定半徑r,求圓的面積。圓的面積應精確到小數點后5位。 例子: 輸入:r 5 輸出:78.53982 解釋:由于面積 PI * r * r 3.14159265358979323846 * 5 * 5 78.53982,因為我們只保留小數點后 5 位數字。 輸…

C++_哈希表

本篇文章是對C學習的哈希表部分的學習分享 相信一定會對你有所幫助~ 那咱們廢話不多說,直接開始吧! 一、基礎概念 1. 哈希核心思想: 哈希函數的作用:通過此函數建立一個Key與存儲位置之間的映射關系。理想目標:實現…

Mac M芯片 RAG 極簡流程 安裝 ragflow + LM studio

本文基于 【【知識科普】【純本地化搭建】【不本地也行】DeepSeek RAGFlow 構建個人知識庫】 https://www.bilibili.com/video/BV1WiP2ezE5a/?share_sourcecopy_web&vd_source9a55f12dd64d8e30ab6c0efc62844343 1 .docker-compose yml文件修改,指定平臺 platform: linux/…

Rsync+inotify+nfs實現數據實時備份方案

技術棧 NFS是 Network File System的簡寫,即網絡文件系統。NFS的優點是內核直接支持,部署簡單、運行穩定,協議簡單、傳輸效率高。缺點是僅依靠IP地址或主機名來決定用戶能否掛載共享目錄,容易出現單點故障。 rsync是linux系統下的…

Vue ⑥-路由

單頁應用程序 單頁應用程序,即 Single-Page Application,簡稱 SPA,是一種使用 JavaScript、HTML 和 CSS 構建的 Web 應用程序。SPA 的核心是前端路由,它使得用戶在訪問網站時,只需加載一次頁面,然后通過前…

Hadoop復習(九)

Azkaban工作流管理器 選擇 問題 1 判斷題 2 / 2 分 工作流是指具有依賴的一組job任務,被依賴的job任務最后執行 正確 錯誤 問題 2 判斷題 2 / 2 分 Azkaban兼容任何版本的Hadoop 正確 錯誤 問題 3 判斷題 2 / 2 分 獨立服務器模式下,Azkab…

SpringMVC相關知識(二)

一.重定向和轉發 1.ModelandView 設置ModelAndView對象 , 根據view的名稱 , 和視圖解析器跳到指定的頁面 頁面 : {視圖解析器前綴} viewName {視圖解析器后綴} 相關代碼&#xff1a; <!-- 視圖解析器 --> <bean class"org.springframework.web.servlet.vi…

std::ratio 簡單使用舉例

author: hjjdebug date: 2025年 06月 09日 星期一 14:28:40 CST descrip: std::ratio 簡單使用舉例 文章目錄 1. 先看一個簡單的例子 1/2/1/35/62 std::ratio 的手冊頁3. std::ratio_add 到底是什么呢&#xff1f;4. 代碼注釋5. 加深理解.6. 自定義的std::ratio 與 std::ratio_…

Docker 優勢與缺點全面解析:容器技術的利與弊

在當今云計算、微服務、DevOps盛行的時代&#xff0c;Docker 幾乎成了開發者、運維工程師的標配工具之一。自2013年誕生以來&#xff0c;Docker 以其輕量、快速、易移植的特點&#xff0c;徹底改變了應用的構建、交付與部署方式。 但任何技術都有兩面性&#xff0c;Docker 也不…

大語言模型(LLM)中的KV緩存壓縮與動態稀疏注意力機制設計

隨著大語言模型&#xff08;LLM&#xff09;參數規模的增長&#xff0c;推理階段的內存占用和計算復雜度成為核心挑戰。傳統注意力機制的計算復雜度隨序列長度呈二次方增長&#xff0c;而KV緩存的內存消耗可能高達數十GB&#xff08;例如Llama2-7B處理100K token時需50GB內存&a…

排序算法總結(C++)

目錄 一、穩定性二、排序算法選擇、冒泡、插入排序歸并排序隨機快速排序堆排序基數排序計數排序 三、總結 一、穩定性 排序算法的穩定性是指&#xff1a;同樣大小的樣本 **&#xff08;同樣大小的數據&#xff09;**在排序之后不會改變原始的相對次序。 穩定性對基礎類型對象…

使用Redis作為緩存優化ElasticSearch讀寫性能

在現代數據密集型應用中,ElasticSearch憑借其強大的全文搜索能力成為許多系統的首選搜索引擎。然而,隨著數據量和查詢量的增長,ElasticSearch的讀寫性能可能會成為瓶頸。本文將詳細介紹如何使用Redis作為緩存層來顯著提升ElasticSearch的讀寫性能,包括完整的架構設計、詳細…

獲取wordpress某個欄目的內容數量

獲取wordpress某個欄目的內容數量 <?php // 將以下 8 改成你的分類 ID 即可echo get_category(8)->count;?> 在制作wordpress模板時&#xff0c;有時會需要調用某個分類目錄下的所有內容數量&#xff0c;通過這段簡潔的代碼就可以實現。 給WordPress自定義字段加…

uniapp 安卓 APP 后臺持續運行(保活)的嘗試辦法

在移動應用開發領域&#xff0c;安卓系統的后臺管理機制較為復雜&#xff0c;應用在后臺容易被系統回收&#xff0c;導致無法持續運行。對于使用 Uniapp 開發的安卓 APP 來說&#xff0c;實現后臺持續運行&#xff08;保活&#xff09;是很多開發者面臨的重要需求&#xff0c;比…

深度學習——知識提煉

第一部分&#xff1a;引言與背景——為什么需要知識提煉&#xff1f; 一、模型壓縮的背景 隨著深度學習的發展&#xff0c;模型變得越來越大&#xff08;如 ResNet152、BERT、ViT、GPT 等&#xff09;&#xff0c;其參數量動輒數億甚至上百億。這些大模型雖然性能強大&#x…

開源之夏·西安電子科技大學站精彩回顧:OpenTiny開源技術下沉校園,點燃高校開發者技術熱情

開源之夏2025編程活動正在如火如荼的進行中&#xff0c;當前也迎來了報名的倒計時階段&#xff0c;開源之夏組織方也通過高校行系列活動進入各大高校&#xff0c;幫助高校開發者科普開源文化、開源活動、開源技術。 6月4日 開源之夏攜手多位開源技術大咖、經驗型選手走進西安電…

時間復雜度和算法選擇

數據范圍 時間復雜度 算法選擇 n \leq 30 指數級別 O(2^n) 深度優先搜索&#xff08;DFS&#xff09; 剪枝、狀態壓縮動態規劃 n \leq 100 O(n^3) Floyd 算法、動態規劃、高斯消元 n \leq 1000 O(n^2) 、 O(n^2 \log n) 動態規劃、二分…

數據分析實戰2(Tableau)

1、Tableau功能 數據賦能&#xff08;讓業務一線也可以輕松使用最新數據&#xff09; 分析師可以直接將數據看板發布到線上自動更新看板自由下載數據線上修改圖表郵箱發送數據設置數據預警 數據探索&#xff08;通過統計分析和數據可視化&#xff0c;從數據發現問題&#xf…