我正在研究从国家地震信息中心(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
请注意经度将转换为东经(因此符号更改)。
我希望解决方案位于awk
,python
或unix shell
命令中,但我会接受ruby
或perl
(我可能不会理解发生了什么。)
答案 0 :(得分:3)
为什么不使用其中一种XML格式的Feed,例如this one。我确信它更容易解析。
答案 1 :(得分:2)
使用正则表达式解析html通常被认为是一个非常非常糟糕的主意,所以我第二次提出使用RSS提要的Abizern建议。事实上,USGS也提供XML下载(见http://earthquake.usgs.gov/earthquakes/catalogs/)。
如果由于某种原因你不能这样做并且 使用html,那么<pre>
块没有进一步的结构(排除一些像lxml或beautifulsoup一样的好东西)然后以下python适用于此单示例...正则表达式可能非常脆弱(坦率地说,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,尽管你可以:)
答案 2 :(得分:1)
这是一个awk脚本,可以帮助你完成大部分工作。转换Lon,date,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