Licznik odkrytych planet dla programistów

NASA na swojej stronie planetquest.jpl.nasa.gov oferuje widżety desktopowe wyświetlające licznik odkrytych pozasłonecznych planet. W prosty sposób możemy wykorzystać źródło danych widżetu by wyświetlić te same dane na własnej stronie za pomocą PHP, czy Pythona. Widżet pobiera dane z dokumentu XML: planetstats.cfm, który możemy pobrać i sparsować wydobywając potrzebne dane.

PHP

Poniżej prosty przykład jak pobrać i sparsować dokument za pomocą SimpleXML (PHP5):
<?php
$xml = simplexml_load_file('http://planetquest.jpl.nasa.gov/atlas/xml/planetstats.cfm');
print_r((string)$xml->planetcount);
print_r((string)$xml->starcount);
print_r((string)$xml->mpscount);
print_r((string)$xml->earthcount);
print_r((string)$xml->lpurl);
print_r((string)$xml->lpname);
print_r((string)$xml->lpdistance);
print_r((string)$xml->lpsize);
print_r((string)$xml->lpsizecomp);
print_r((string)$xml->lpsizegtlt);
print_r((string)$xml->lporbit);
print_r((string)$xml->lpimagethm);
gdzie:
  • planetcount: ilość odkrytych planet
  • starcount: ilość gwiazd z planetami
  • mpscount: ilość układów z wieloma planetami
  • earthcount: ilość planet typu ziemskiego
  • lpurl: adres URL do profilu "ostatnio odkrytej" planety
  • lpname: nazwa planety
  • lpdistance: odległość od Ziemi w latach świetlnych
  • lpsize: rozmiar planety
  • lpsizecomp: planeta Układu Słonecznego względem którego podany jest rozmiar
  • lporbit: dni na okrążenie gwiazdy
  • lpimagethm: miniaturka (nazwa pliku, pełen URL to http://planetquest.jpl.nasa.gov/atlas/images/NAZWA_PLIKU)
Jeżeli planujemy wykorzystać te dane na stronie ze sporym ruchem to warto keszować pobrane dane - czy to poprzez system keszowania szablonów aplikacji, lub pobierając dane XML i zapisując je do pliku do ponownego wykorzystania przez określony okres czasu (np. 24 godziny).

Python

Poniżej kod dla Pythona z rozdzielonym pobieraniem pliku i jego parsowaniem:
# -*- coding: utf-8 -*-
import urllib2
from xml.dom import minidom

url = 'http://planetquest.jpl.nasa.gov/atlas/xml/planetstats.cfm'

opener = urllib2.build_opener()
d = opener.open(url)
data = d.read()
cache = open('planets.xml', 'w')
cache.write(data)
cache.close()
print 'dane zapisane'

DOMTree = minidom.parse('planets.xml')
cNodes = DOMTree.childNodes

i = cNodes[0]
planetcount = i.getElementsByTagName("planetcount")[0].childNodes[0].toxml()
starcount = i.getElementsByTagName("starcount")[0].childNodes[0].toxml()
mpscount = i.getElementsByTagName("mpscount")[0].childNodes[0].toxml()
earthcount = i.getElementsByTagName("earthcount")[0].childNodes[0].toxml()
lpurl = i.getElementsByTagName("lpurl")[0].childNodes[0].toxml()
lpname = i.getElementsByTagName("lpname")[0].childNodes[0].toxml()
lpdistance = i.getElementsByTagName("lpdistance")[0].childNodes[0].toxml()
lpsize = i.getElementsByTagName("lpsize")[0].childNodes[0].toxml()
lpsizecomp = i.getElementsByTagName("lpsizecomp")[0].childNodes[0].toxml()
lpsizegtlt = i.getElementsByTagName("lpsizegtlt")[0].childNodes[0].toxml()
lporbit = i.getElementsByTagName("lporbit")[0].childNodes[0].toxml()
lpimagethm = i.getElementsByTagName("lpimagethm")[0].childNodes[0].toxml()

print planetcount
print starcount
print mpscount
print earthcount
print lpurl
print lpname
print lpimagethm
Teraz gdybyśmy chcieli dodać keszowanie pobranego dokumentu przez 24 godziny to można zrobić to tak:
# -*- coding: utf-8 -*-
import urllib2
from xml.dom import minidom
from time import time
from os.path import isfile, getmtime

url = 'http://planetquest.jpl.nasa.gov/atlas/xml/planetstats.cfm'


if isfile('planets.xml') and getmtime('planets.xml') > time()-86400:
	print 'dane z cache'
else:
	opener = urllib2.build_opener()
	d = opener.open(url)
	data = d.read()
	cache = open('planets.xml', 'w')
	cache.write(data)
	cache.close()
	print 'dane zapisane'

DOMTree = minidom.parse('planets.xml')
cNodes = DOMTree.childNodes

i = cNodes[0]
planetcount = i.getElementsByTagName("planetcount")[0].childNodes[0].toxml()
starcount = i.getElementsByTagName("starcount")[0].childNodes[0].toxml()
mpscount = i.getElementsByTagName("mpscount")[0].childNodes[0].toxml()
earthcount = i.getElementsByTagName("earthcount")[0].childNodes[0].toxml()
lpurl = i.getElementsByTagName("lpurl")[0].childNodes[0].toxml()
lpname = i.getElementsByTagName("lpname")[0].childNodes[0].toxml()
lpdistance = i.getElementsByTagName("lpdistance")[0].childNodes[0].toxml()
lpsize = i.getElementsByTagName("lpsize")[0].childNodes[0].toxml()
lpsizecomp = i.getElementsByTagName("lpsizecomp")[0].childNodes[0].toxml()
lpsizegtlt = i.getElementsByTagName("lpsizegtlt")[0].childNodes[0].toxml()
lporbit = i.getElementsByTagName("lporbit")[0].childNodes[0].toxml()
lpimagethm = i.getElementsByTagName("lpimagethm")[0].childNodes[0].toxml()

print planetcount
print starcount
print mpscount
print earthcount
print lpurl
print lpname
print lpimagethm
Gdzie najważniejszy jest warunek:
if isfile('planets.xml') and getmtime('planets.xml') > time()-86400:
Sprawdzamy czy plik istnieje i czy jego data modyfikacji (wyrażona znacznikiem czasu) nie jest starsza niż 24. Jeżeli warunki te są spełnione - używamy danych w pliku (kesz), a jeżeli nie to pobieramy nowe dane i zapisujemy do pliku.
RkBlog

Oprogramowanie astronomiczne, 6 November 2009

Comment article
Comment article RkBlog main page Search RSS Contact