Mercurial > ~darius > hgwebdir.cgi > scrape-vb
diff scrape-vb.py @ 1:8045db05180b SCRAPEVB_1_0
Initial revision
author | darius |
---|---|
date | Sat, 25 Aug 2007 05:17:29 +0000 |
parents | |
children | 89232ea0c3d4 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/scrape-vb.py Sat Aug 25 05:17:29 2007 +0000 @@ -0,0 +1,158 @@ +#!/usr/bin/env python + +############################################################################ +# Screen scraper for Virgin Blue to look for happy hour deals +# +# Prints out (and emails) when criteria match based on cost, +# destination, etc +# +# $Id: scrape-vb.py,v 1.1.1.1 2007/08/25 05:17:29 darius Exp $ +############################################################################ +# +# Copyright (C) 2007 Daniel O'Connor. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND +# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE +# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +# SUCH DAMAGE. +# +############################################################################ + +import re, BeautifulSoup, datetime, time, smtplib, sys, urllib + +#### Configuration + +### Travel criteria +# Supported keys are email, when, city1, city2, maxcost +# email is mandatory. If city2 is not present either city will be +# matched. when and maxcost are optional (will match for any date or +# cost) +travellers = [ + { 'email' : 'darius@dons.net.au', 'city1' : 'Sydney' }, + { 'email' : 'sarah.mahoney@nehta.gov.au', 'city1' : 'Adelaide', 'city2' : 'Brisbane' }, + ] + +### Mail host +mailhost = 'mail.dons.net.au' + +### Who the email is from +mailfrom = 'darius@dons.net.au' + +### What's onn the subject linee +mailsubj = 'Virgin Blue Happy Hour Deals' + +### Actually send email? +mailsend = False + +### URL to parse +vburl = 'http://virginblue.com.au' + +parsetitle = re.compile('([a-z ]+) - ([a-z ]+) \$([0-9]+)', re.IGNORECASE) +parsetper = re.compile('Travel Period: ([0-9]+/[0-9]+/[0-9]+) - ([0-9]+/[0-9]+/[0-9]+)', re.IGNORECASE) + +try: + #f = open("vb-happyhour.html") + f = urllib.urlopen(vburl) +except IOError, e: + print "Unable to fetch page - " + str(e) + sys.exit(1) + +s = BeautifulSoup.BeautifulSoup(f) +hrr = s.find("ul", "happyhr-rows") +if (hrr == None): + print "No happy hour details found" + sys.exit(0) + +hrlist = hrr.findAll("li") + +# XXX: I wanted to use findAll('ul', 'happyhr-conditions') but it +# doesn't work +times = parsetper.match(s.findAll('ul')[11].find('li').string) +if (times == None): + print "Unable to parse travel period " + parsetper.match(s.findAll('ul')[11].find('li')) + sys.exit(0) + +frtime = datetime.datetime(*time.strptime(times.group(1), "%d/%m/%y")[0:3]) +totime = datetime.datetime(*time.strptime(times.group(2), "%d/%m/%y")[0:3]) + +#print "Travel from %s to %s" % (str(frtime), str(totime)) + +output = {} +for i in hrlist: + href = i.find('a') + match = parsetitle.match(href['title']) + if (match == None): + print "Unable to match " + str(s) + continue + + city1 = match.group(1) + city2 = match.group(2) + cost = int(match.group(3)) + url = href['href'] + + for t in travellers: + if ('email' not in t): + print "No email key found, configuration error?" + continue + + citymatch = True + if ('city1' in t and 'city2' in t): + if((t['city1'] != city1 or t['city2'] != city2) and + (t['city1'] != city2 or t['city2'] != city1)): + citymatch = False + elif ('city1' in t): + if (t['city1'] != city1 and t['city1'] != city2): + citymatch = False + + datematch = True + if ('when' in t): + travtime = datetime.datetime(*time.strptime(t['when'], "%d/%m/%y")[0:3]) + if (travtime < frtime or travtime > totime): + datematch = False + + costmatch = True + if ('maxcost' in t): + if (cost > int(t['maxcost'])): + costmatch = False + + if (citymatch and datematch and costmatch): + if (t['email'] not in output): + + output[t['email']] = [] + output[t['email']].append([city1, city2, cost, url]) + +if (mailsend): + server = smtplib.SMTP(mailhost) + #server.set_debuglevel(1) + +for o in output: + msg = ("From: %s\r\nTo: %s\r\nSubject: %s\r\n\r\n" % (mailfrom, o, mailsubj)) + msg = msg + "Your criteria for flights have been matched\r\n\r\n" + print "Sending email to " + o + for i in output[o]: + print "%s <-> %s costs $%d" % (i[0], i[1], i[2]) + msg = msg + "%s <-> %s costs $%d - %s\r\n" % (i[0], i[1], i[2], i[3]) + + msg = msg + "\r\nNote: travel period is from %s to %s" % \ + (frtime.strftime("%A %e %B %Y"), totime.strftime("%A %e %B %Y")) + if (mailsend): + server.sendmail(mailfrom, o, msg) + else: + print msg + print