錯誤訊息
File "D:/readweather.py", line 15, in parse_html
with open(arg,'r',encoding='utf-8') as f:
FileNotFoundError: [Errno 2] No such file or directory: 'HTML_DATA\\2018-01-01_466910.htm'
import datetime as dt
import re
#######################################################################
#自訂函式區
def parse_html(arg):
with open(arg,'r',encoding='utf-8') as f:
content=f.read()
f.close()
content=content.replace(' ','').replace(' ','').replace('\t','').replace('\n','').replace(' ','')
hours_data=re.findall('<tr><td nowrap>([^<]+)</td><td>([^<]+)</td><td>([^<]+)</td><td>([^<]+)</td><td>([^<]+)</td><td>([^<]+)</td><td>([^<]+)</td><td>([^<]+)</td><td>([^<]+)</td><td>([^<]+)</td><td>([^<]+)</td><td>([^<]+)</td><td>([^<]+)</td><td>([^<]+)</td><td>([^<]+)</td><td>([^<]+)</td><td>([^<]+)</td></tr>', content)
return hours_data
學著看debug訊息啊。python的很詳細。
哪天真的要我寫一本語言的書,一定把錯誤訊息放在前幾章。XD
FileNotFoundError就是找不到你要開的檔案。
因為你寫的是相對目錄,你必須先知道你目前的工作目錄在哪。
不知道你是如何執行py檔的。
如果是利用絕對目錄執行,那就要去看你工作目錄。
c:\users\aaa>python d:\webCrawler\xxx.py
這樣的話,你的py檔會去讀 c:\users\aaa\HTML_DATA\2018-01-01_466910.htm
而不是 d:\webCrawler\HTML_DATA\2018-01-01_466910.htm
另外補充一招,通常我都會把他轉成絕對目錄處理。
import os
pyDir = os.path.dirname(os.path.absname(__file__))
with open(os.path.join(pyDir, "HTML_DATA\\2018-01-01_466910.htm"), "r") as f:
pass
斯斯有兩種,
File no found 也有兩種 一種是路徑問題 另一種就是檔案真的不在該資料夾裡...
根據我過人的眼力
他應該是第二種
2018-01-01_466910.htm
我知道錯誤訊息 FileNotFoundError 就是找不到你要開的檔案 , 所以我把檔案目錄貼上來 , 不是就在 D:\HTML_DATA\ 下面 , 是指定相對目錄設定錯誤 ?
我的 PY 是這樣執行的 , 先執行下面
import datetime as dt #將函數 datetime 指定給 dt
import requests,time,pathlib,os,re #輸入需要的函數
#######################################################################
#自訂函式區
def get_url_filename(arg): # 取得網頁檔案 arg能夠接收不定量的非關鍵字參數
return re.sub(r'^.*?station=(.*?)&stname=&datepicker=(.*?)$',r'\2_\1',arg)
#re.sub屬於python正則的標準庫,主要是的功能是用正則匹配要替換的字串
def log(arg): # log函數是代表記錄的log
with open('log\\event.log','a',encoding='utf-8') as f: #打開event.log 'a'新的內容將會被寫入到已有內容之後。如果該文件不存在,創建新文件進行寫入。 utf-8 中文編碼
f.writelines(arg+'\n') # f=file 寫入行並換行
f.close() # 關檔
#######################################################################
base_dir = os.path.dirname(os.path.realpath(__file__))
#判斷log資料夾是否存在,若不存在則建立log資料夾
pathlib.Path(base_dir+"\\log\\").mkdir(parents=True, exist_ok=True)
with open('log\\event.log','w',encoding='utf-8') as f: #把open那邊傳回來的值存入f這個變數
pass #這裡用意是把event.log內容清空
f.close()
location_dict={'466910':'鞍部','466920':'臺北','466930':'竹子湖','C0A980':'社子','C0A9A0':'大直','C0A9B0':'石牌','C0A9C0':'天母','C0A9E0':'士林','C0A9F0':'內湖','C0AC40':'大屯山','C0AC70':'信義','C0AC80':'文山','C0AH40':'平等','C0AH70':'松山','C1AC50':'關渡','C1A730':'公館','C0A9G0':'南港','C0A990':'大崙尾山'}
#print(location_dict.keys()) 測試列出location_dict所有key:466910,466920...
#下載日期起點終點
startdate = dt.datetime(2019, 8,1)
enddate = dt.datetime(2019, 8,1)
totaldate = (enddate - startdate).days + 1
data_folder='HTML_DATA'
#判斷HTML_DATA資料夾是否存在,若不存在則建立HTML_DATA資料夾
pathlib.Path(data_folder).mkdir(parents=True, exist_ok=True)
#######################################################################
#下載全部html資料到HTML_DATA資料夾
for daynumber in range(totaldate): # 迴圈 日期數目在全部日期的範圍內
datestring = str((startdate + dt.timedelta(days = daynumber)).date())
#將日期轉換為字串
print(datestring)
#取得單日_全部地點.htm
for i in location_dict.keys(): # 迴圈 i 從監測站起點到終點下載資料
url="https://e-service.cwb.gov.tw/HistoryDataQuery/DayDataController.do?command=viewMain&station=%s&stname=&datepicker=%s" %(i.split("_")[0],datestring)
#print(url)
try: #異常狀況處裡 ,避免當機產生
r=requests.get(url) ## 使用 GET 方式下載普通網頁
print("Download: "+datestring+"_"+i+".htm") #列印下載日期 , 當 i 迴圈中斷的地方
with open(data_folder+"\\"+datestring+"_"+i+".htm",'w',encoding='utf-8') as f:
#打開檔案目錄與日期在 i 迴圈
f.write(r.text) #寫入 r.text 檔案
f.close() # 關閉
except:
print("Error: "+datestring+"_"+i+".htm")
#列印錯誤日期在迴圈 i 的何處停止
log(url)
finally:
time.sleep(5)
print("1. HTML資料下載完畢.")
#######################################################################
#檢查event.log是否為空或有內容,有則表示有資料下載失敗需要重新下載
log_file = (open("log\\event.log", "r"))
download_error_url = log_file.read().split('\n')
log_file.close()
#若download_error_url陣列長度為1時表示是沒有錯誤(只有一列空白行)
#大於1表示有下載錯誤的記錄
if (len(download_error_url))>1: #假如下載錯誤網址長度>1
with open('log\\event.log','w',encoding='utf-8') as f:
pass #這裡用意是把event.log內容清空
f.close()
for i in download_error_url: # 迴圈 i 在 下載錯誤網址
if i!='': #假如 i 不等於空白
try: # 異常處理同上
r=requests.get(i)
print("Download: "+get_url_filename(i)+".htm")
with open(data_folder+"\\"+get_url_filename(i)+".htm",'w',encoding='utf-8') as f:
f.write(r.text)
f.close()
except:
print("Error: "+get_url_filename(i)+".htm")
log(i)
finally:
time.sleep(5)
print("2. 下載錯誤HTML資料補下載完畢.")
else:
print("2. 檢查完畢,無下載錯誤HTML資料.")
再執行下面
import datetime as dt
import re
#######################################################################
#自訂函式區
def parse_html(arg):
with open(arg,'r',encoding='utf-8') as f:
content=f.read()
f.close()
content=content.replace(' ','').replace(' ','').replace('\t','').replace('\n','').replace(' ','')
hours_data=re.findall('<tr><td nowrap>([^<]+)</td><td>([^<]+)</td><td>([^<]+)</td><td>([^<]+)</td><td>([^<]+)</td><td>([^<]+)</td><td>([^<]+)</td><td>([^<]+)</td><td>([^<]+)</td><td>([^<]+)</td><td>([^<]+)</td><td>([^<]+)</td><td>([^<]+)</td><td>([^<]+)</td><td>([^<]+)</td><td>([^<]+)</td><td>([^<]+)</td></tr>', content)
return hours_data
#######################################################################
location_dict={'466910':'鞍部','466920':'臺北','466930':'竹子湖','C0A980':'社子','C0A9A0':'大直','C0A9B0':'石牌','C0A9C0':'天母','C0A9E0':'士林','C0A9F0':'內湖','C0AC40':'大屯山','C0AC70':'信義','C0AC80':'文山','C0AH40':'平等','C0AH70':'松山','C1AC50':'關渡','C1A730':'公館','C0A9G0':'南港','C0A990':'大崙尾山'}
#print(location_dict.keys()) 測試列出location_dict所有key:466910,466920...
startdate = dt.datetime(2018, 1,1)
enddate = dt.datetime(2018, 1,2)
totaldate = (enddate - startdate).days + 1
data_folder='HTML_DATA'
#######################################################################
#讀取HTML_DATA資料夾內全部html文件,解析HTML源碼後存為weather.csv
with open('weather.csv','w',encoding='utf-8') as f:
f.writelines('Station,ObsTime,StnPres,SeaPres,Temperature,Td dew point,RH,WS,WD,WSGust,WDGust,Precp,PrecpHour,SunShine,GloblRad,Visb,UVI,Cloud Amount\n')
for daynumber in range(totaldate):
datestring = str((startdate + dt.timedelta(days = daynumber)).date())
#print(datestring)
#取得單日_全部地點.htm
for i in location_dict.keys():
print(datestring+str(i))
hours_arr=parse_html(data_folder+"\\"+datestring+"_"+i+".htm")
for j in hours_arr:
print("%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s\n"%(i,datestring+' '+j[0]+':00:00',j[1],j[2],j[3],j[4],j[5],j[6],j[7],j[8],j[9],j[10],j[11],j[12],j[13],j[14],j[15],j[16]))
#f.writelines("%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s\n"%(location_dict[i],datestring+' '+(j[0] if j[0]!='24' else '00')+':00:00',j[1],j[2],j[3],j[4],j[5],j[6],j[7],j[8],j[9],j[10],j[11],j[12],j[13],j[14],j[15],j[16]))
f.writelines("%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s\n"%(i,datestring+' '+(j[0] if j[0]!='24' else '00')+':00:00',j[1],j[2],j[3],j[4],j[5],j[6],j[7],j[8],j[9],j[10],j[11],j[12],j[13],j[14],j[15],j[16]))
f.close()
你有發現1.py跟2.py兩個的日期設定不一樣嗎,你抓htm設2019,8,1~2019,8,1,讀htm設2018,1,1~2018,1,2,這樣怎會不出錯?
把1.py的日期設2018,1,1~2018,1,2,存檔再重跑一遍1.py 2.py看看,應該就OK了
謝謝 ! 發現了 , 可以執行了
GOOD JOB~
我換了這行 , 應該變中文 , 怎麼變亂碼 , 主要是 location_dict[i] 的差別
f.writelines("%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s\n"%(location_dict[i],datestring+' '+(j[0] if j[0]!='24' else '00')+':00:00',j[1],j[2],j[3],j[4],j[5],j[6],j[7],j[8],j[9],j[10],j[11],j[12],j[13],j[14],j[15],j[16]))
我的程度只有 99 乘法與判斷數字大小 , 接近百行的程式 , 還要慢慢加強才行
所以說你不要急於寫爬蟲啊,先練基本工,要不然你根本不懂你寫的是什麼,你要怎麼寫?
先把你每一行程式碼在寫什麼,為什麼要傳這些參數,裡面用到的函數接收什麼參數,吐出什麼參數搞清楚。
寫程式就像演講一樣,一個語言你連詞彙都還不會,你要怎麼做一場精彩的演講?
因為我們小組要交專題 9/24 就結業了 , 所以要寫爬蟲抓資料分析 , 我們小組有 6 個人 , 一個以前寫過 C , 他比較會寫 , 但也不能只靠他一個人 , 所以我們要分擔工作 , 我就寫爬蟲從中在學
kevin543
有個鐵人賽作者 心原一馬 他的Python超入門全部篇章推薦你完整一字不露的看個十遍,然後把範例自己keyin十遍執行看看,應該會對基礎有幫助。
【Python 超入門】(1) 心原一馬從零開始帶你學程式
https://ithelp.ithome.com.tw/articles/10211960
好奇你們的專題是什麼?
爬蟲+web弄個資訊站這樣?
UBIKE 使用特性資料分析 , 包括使用率 熱冷門站點 熱門路線 平日假日租借分析 雨天租借使用率.... 等等
如果工作還沒分配下去的話,我會建議:
爬蟲請會寫c語言的寫,你們不會的寫那些統計功能。
python因為內建函式庫比較齊全,要寫那些功能比爬蟲容易,也可以順便練習語法和寫程式的感覺
如果不要介面的話,你們的專題聽起來還蠻簡單的,難度應該不會太過。
說嚴厲點,資策會的課程也蠻貴的,去學了卻沒獨力完成的能力的話,真的要檢討一下夠不夠努力了。
謝謝指點 , 資料都抓完了 , 剩下統計功能 , 我們就可以完成了
我們班 34 個人 , 是勞動部失業補助課程 , 女生佔一半 , 會寫的幾乎都是男生 , 也都是之前有寫過的 , 沒寫過上課後會寫的很少 , 同學也都很認真 , 少數幾個屁孩打混外 , 其他上課都常發問 , EXCEL 函數分析大家都比較熟 , 程式強的就不多