2009-11-27 4 views
2

j'ai le script suivant j'utilise des données ferraille de mon site Web uni et l'insérer dans un GAE Dboptimisation de script python pour le moteur d'application

from mechanize import Browser 
from BeautifulSoup import BeautifulSoup 
import re 
import datetime 

__author__ = "Nash Rafeeq" 

url = "http://webspace.apiit.edu.my/schedule/timetable.jsp" 
viewurl = "http://localhost:8000/timekeeper/intake/checkintake/" 
inserturl = "http://localhost:8000/timekeeper/intake/addintake/" 
print url 
mech = Browser() 
try: 
    page = mech.open(url) 
    html = page.read() 
except Exception, err: 
    print str(err) 
#print html 
soup = BeautifulSoup(html) 
soup.prettify() 
tables = soup.find('select') 
for options in tables: 
    intake = options.string 
    #print intake 
    try: 
     #print viewurl+intake 
     page = mech.open(viewurl+intake) 
     html = page.read() 
     print html 
     if html=="Exist in database": 
      print intake, " Exist in the database skiping" 
     else: 
      page = mech.open(inserturl+intake) 
      html = page.read() 
      print html 
      if html=="Ok": 
       print intake, "added to the database" 
      else: 
       print "Error adding ", intake, " to database" 
    except Exception, err: 
     print str(err) 

je me demande quelle serait la meilleure façon d'optimiser ce script donc je peux l'exécuter sur les serveurs du moteur de l'application. comme il est, il râpe maintenant plus de 300 entrées et prendre plus de 10 minutes pour insérer toutes les données sur ma machine locale

le modèle qui est utilisé pour stocker les données

class Intake(db.Model): 
    intake=db.StringProperty(multiline=False, required=True) 
    #@permerlink  
    def get_absolute_url(self): 
     return "/timekeeper/%s/" % self.intake 
    class Meta: 
     db_table = "Intake" 
     verbose_name_plural = "Intakes" 
     ordering = ['intake'] 

Répondre

4

Divide and conquer.

  1. Faites une liste des tâches (par exemple urls Gratter/parse)
  2. Ajouter vos tâches dans une file d'attente (appengine taskqueue api, amazon sqs, ...)
  3. Process votre file d'attente
+0

+1 pour la fracture et de la stratégie Conquer: à ne pas manquer! – jldupont

+0

il est seulement grattage d'une url. ce qui est en train d'être gratté est une liste d'options qui compte plus de 300 entrées. Donc, si je le divise en tâches, il va être deux tâches. Je devine un pour le grattage et un pour l'insertion. cela fonctionnerait-il sans dépasser les limites de quota? ou est leur autre façon d'optimiser. noob total ici donc s'il vous plait portez sur moi –

+0

Dans le code que vous avez collé, vous faites des demandes répétées dans une boucle for - donc ce n'est pas un seul fetch. –

2

La première chose vous devez réécrire votre script pour utiliser directement la banque de données App Engine. Une grande partie du temps que vous dépensez est sans doute parce que vous utilisez des requêtes HTTP (deux par entrée!) Pour insérer des données dans votre banque de données. L'utilisation directe du magasin de données avec batch puts devrait réduire de quelques ordres de grandeur votre temps d'exécution.

Si votre code d'analyse est encore trop lent, vous pouvez découper le travail en blocs et utiliser le task queue API pour effectuer le travail dans plusieurs requêtes.

1

salut selon la Tosh et nick i ont modifié le script comme ci-dessous

from google.appengine.api import urlfetch 
from BeautifulSoup import BeautifulSoup 
from timkeeper.models import Intake 
from google.appengine.ext import db 

__author__ = "Nash Rafeeq" 

url = "http://webspace.apiit.edu.my/schedule/timetable.jsp" 
try: 
    page = urlfetch.fetch(url) 
    #print html 
    soup = BeautifulSoup(page.content) 
    soup.prettify() 
    tables = soup.find('select') 
    models=[] 
    for options in tables: 
     intake_code = options.string 
     if Intake.all().filter('intake',intake_code).count()<1: 
      data = Intake(intake=intake_code) 
      models.append(data) 
    try: 
     if len(models)>0: 
      db.put(models) 
     else: 
      pass 
    except Exception,err: 
     pass 
except Exception, err: 
    print str(err) 

suis-je sur la bonne voie? Aussi, je ne suis pas vraiment sûr de savoir comment obtenir ce à invoquer sur un calendrier (une fois par semaine) quelle serait la meilleure façon de le faire?

et merci pour les réponses rapides

+0

Vous pouvez vous intéresser au service cron de l'application. http://code.google.com/appengine/docs/python/config/cron.html – tosh