Skip to content

Instantly share code, notes, and snippets.

@hyakuhei
Created April 17, 2015 15:57
Show Gist options
  • Save hyakuhei/ff9b4d33ac90e9ec8788 to your computer and use it in GitHub Desktop.
Save hyakuhei/ff9b4d33ac90e9ec8788 to your computer and use it in GitHub Desktop.
'''
Created on 16 Apr 2015
@author: robert
'''
import lxml.html as html
import requests
import logging
import time
logger = logging.getLogger(__name__)
class TideScraper():
def scrapeTideForecast(self,location):
page = requests.post("http://www.tide-forecast.com/locations/catch",data={'query':location})
root = html.document_fromstring(page.text)
scripts = root.xpath("//script[@src]")
locname = None
for script in scripts:
if location.lower() in script.get('src').lower():
for part in script.get('src').split("/"):
if location.lower() in part.lower():
locname = part.split(".")[0]
if not locname:
logger.error("Could not find location {}".format(location))
return
data = []
page = requests.get("http://www.tide-forecast.com/tides/{}.js".format(locname))
if page.status_code != 200:
logger.error(page.text)
logger.error('locname = {}'.format(locname))
for line in page.text.split():
cleanline = line.strip('[').strip(',').strip(']')
elements = cleanline.split(",")
if len(elements) == 4:
ld = {'x':int(elements[0]),
'y':int(elements[1]),
'epoch':int(elements[2]),
'height':float(elements[3]),
}
data.append(ld)
return data
def getHeightsForDays(self,data):
#Convert some times
days = {}
for entry in data:
entry['timestr'] = time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(entry['epoch']))
ydelta = time.localtime(entry['epoch'] + entry['y'])
entry['date'] = time.strftime("%d-%m-%Y", ydelta)
entry['time'] = time.strftime("%H:%M:%S", ydelta)
if entry['date'] not in days:
days[entry['date']] = []
days[entry['date']].append(entry)
#if entry['date'] == '17-04-2015':
# logger.info("{} - {:.1f}m".format(entry['time'],entry['height']))
return days
def getTides(self,dataset):
tides = []
state = 'unknown'
for i in range(1,len(dataset)):
if state == 'unknown':
if dataset[i]['height'] < dataset[i-1]['height']:
state = 'dropping'
else:
state = 'rising'
#Rather than looking for the lowest value we look for when the tide turns
#Possibly need to introduce some countback in case data sets are the same ie slack water
if state == 'dropping':
if dataset[i]['height'] > dataset[i-1]['height']:
#logger.debug("{} {:.1f}m - Low tide".format(dataset[i-1]['time'],dataset[i-1]['height']))
tides.append({'time':dataset[i-1]['time'], 'height':dataset[i-1]['height'], 'type':'Low tide'})
state = 'rising'
if state == 'rising':
if dataset[i]['height'] < dataset[i-1]['height']:
#logger.debug("{} {:.1f}m - High tide".format(dataset[i-1]['time'],dataset[i-1]['height']))
tides.append({'time':dataset[i-1]['time'], 'height':dataset[i-1]['height'], 'type':'High tide'})
state = 'dropping'
if dataset[i]['height'] == dataset[i-1]['height']:
logger.info("Two adjacent tides with height {}m".format(dataset[i]['height']))
return tides
if __name__ == '__main__':
logging.basicConfig(level=logging.DEBUG)
ts = TideScraper()
data = ts.scrapeTideForecast("Angochi")
days = ts.getHeightsForDays(data)
print days.keys()
friday = ts.getTides(days['17-04-2015'])
for tide in friday:
print tide
@hyakuhei
Copy link
Author

Some code to scrape the tidal data from tide-forecast.com

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment