2011-06-29 54 views
1

我正在從國家地震信息中心(USGS)自動下載地震參數。不幸的是,他們的格式是一堆廢話,我認爲我不會有太多的運氣說服他們改變他們的格式。所以,我必須格式化它們的<pre> html塊,以便以表格形式表示。字符串塊格式化挑戰

但是我的字符串格式化經驗有限,所以我被卡住了(但是確定有人可能有解決方案)。這裏有一個例子:

curl --silent http://earthquake.usgs.gov/earthquakes/eqinthenews/2010/uu00002715/uu00002715_gcmt.php |\ 
sed -n '/<pre>/,/<\/pre>/p' |\ 
egrep -v '(#)|(pre>)' |\ 
egrep '(MW)|(ORIGIN)|(LAT)|(DEP)|(BEST DBLE)|(NP1)' 

這使我需要格式化的信息:

April 15, 2010, UTAH, MW=4.6 
ORIGIN TIME:  23:59:42.8 0.4 
LAT:41.72N 0.03;LON:110.86W 0.03 
DEP: 12.5 1.8;TRIANG HDUR: 0.6 
BEST DBLE.COUPLE:M0= 1.07*10**23 
NP1: STRIKE=193;DIP=35;SLIP= -80 

我想一個格式像這樣:

name date  time  lon  lat dep dep_err Mw M0  strike dip slip 
UTAH 2010/04/15 23:59:42.8 -110.86 41.72 12.5 1.8  4.6 1.07e23 193 35 -80 

注經度要轉換到東經(因此符號改變)。

我想解決在awkpython,或unix shell命令,但我會招待rubyperl(我只是大概不會明白是怎麼回事)。

回答

1

下面是一個awk腳本,它可以幫助您實現這一目標。改造經度,日期,M0等被作爲一個練習:

curl --silent http://earthquake.usgs.gov/earthquakes/eqinthenews/2010/uu00002715/uu00002715_gcmt.php | 
awk ' 
    BEGIN { 
     FS = "[,:;= ]+" 
     OFS = "^" 
    } 
    /<pre>/ {process=1} 
    /<\/pre>/ {process=0} 
    ! process {next} 
    /MW=/ { 
     date = $1 " " $2 " " $3 
     place = $4 
     mw = $NF 
    } 
    /^ORIGIN TIME:/ { 
     otime = $3 ":" $4 ":" $5 
    } 
    /^LAT:.*LON:/ { 
     lat = $2 
     lon = $5 
    } 
    /^DEP:/ { 
     dep = $2 
     dep_err = $3 
    } 
    /^BEST DBLE.COUPLE:/ { 
     m0 = $NF 
    } 
    /^NP1:/ { 
     strike = $3 
     dip = $5 
     slip = $7 
    } 
    END { 
     print "name", "date", "time", "lon", "lat", "dep", "dep_err", "Mw", "M0", "strike", "dip", "slip" 
     print place, date, otime, lon, lat, dep, dep_err, mw, m0, strike, dip, slip 
    } 
' | column -s^-t 

輸出:

name date   time  lon  lat  dep dep_err Mw M0   strike dip slip 
UTAH April 15 2010 23:59:42.8 110.86W 41.72N 12.5 1.8  4.6 1.07*10**23 193  35 -80 
+0

我很謙虛。非常感謝! –

3

爲什麼不使用其中一個XML格式的提要,如this one。我相信解析起來更容易。

+0

我感謝您的建議。這個問題是科學的:我需要確保他們發佈的(和我正在使用的)解決方案是最終估算 - 不是初始估算。在許多情況下,他們發佈的模型需要幾個小時到幾天才能完善,所以我不能依賴於立即的RSS提要。 –

2

解析HTML正則表達式通常被看作是一個非常,非常糟糕的主意,所以我第二Abizern建議使用RSS提要。實際上,USGS也提供XML下載(請參閱http://earthquake.usgs.gov/earthquakes/catalogs/)。

如果由於某種原因,你不能做到這一點,使用HTML,然後爲<pre>塊沒有進一步的結構(排除一些好聽喜歡使用LXML或beautifulsoup),那麼這樣做的以下蟒蛇作品單個示例...正則表達式可能非常脆弱(坦率地說,cludgey),並且需要調整以處理更多示例/異常。

這寫出一個excel文件,所以你應該能夠彈出所有的循環來刮多個頁面(播放很好,檢查他們的條款,限制速度和緩存)。

import httplib2 
import re 
from xlwt import Workbook 

h = httplib2.Http(".cache") 
url = 'http://earthquake.usgs.gov/earthquakes/eqinthenews/2010/uu00002715/uu00002715_gcmt.php' 
resp, content = h.request(url, "GET") 
regex = re.compile("<pre>\s*(?P<date>.* \d{2}, \d{4}), (?P<name>\w.*), MW=(?P<Mw>\d.\d).*ORIGIN TIME:\s*(?P<time>\d{2}:\d{2}:\d{2}.\d).*LAT:\s*(?P<lat>\d{2,3}.\d{2,3}[N|S]).*LON:\s*(?P<lon>\d{2,3}.\d{2,3}[W|E]).*DEP:\s*(?P<dep>\d{2,3}.\d)\s*(?P<dep_err>\d{1,3}.\d);.*M0=\s*(?P<M0>\d.\d{1,2}\*\d{1,2}\*\*\d{1,2}).*STRIKE=(?P<strike>\d{1,3}).*DIP=(?P<dip>\d{1,3}).*SLIP=\s*(?P<slip>[-|+]\d{1,3}).*NP2",re.MULTILINE|re.DOTALL) 
r = regex.search(content) 
data = r.groupdict() 

headers = ['name', 'date', 'time', 'lon', 'lat', 'dep', 'dep_err', 'Mw', 'M0', 'strike', 'dip', 'slip'] 
wb = Workbook() 
ws = wb.add_sheet('Quakes') 

column = 0 
for header in headers: 
    ws.write(0, column, header) 
    ws.write(1, column,data[header]) 
    column+=1 
wb.save('quakes.xls') 

你應該絕對使用XML/RSS雖然不是如果你能:)

+0

這是一個非常好的解決方案@craigs。問題是,是的,我不得不使用html(請參閱我對@Abizern的迴應)。 –