2013-03-04 15 views
7

Nella mia applicazione python devo leggere molte pagine Web per raccogliere dati. Per ridurre le chiamate http, desidero recuperare solo le pagine modificate. Il mio problema è che il mio codice mi dice sempre che le pagine sono state modificate (codice 200) ma in realtà non lo è.rileva se una pagina web viene modificata

Questo è il mio codice:

from models import mytab 
import re 
import urllib2 
from wsgiref.handlers import format_date_time 
from datetime import datetime 
from time import mktime 

def url_change(): 
    urls = mytab.objects.all() 
    # this is some urls: 
    # http://www.venere.com/it/pensioni/venezia/pensione-palazzo-guardi/#reviews 
    # http://www.zoover.it/italia/sardegna/cala-gonone/san-francisco/hotel 
    # http://www.orbitz.com/hotel/Italy/Venice/Palazzo_Guardi.h161844/#reviews 
    # http://it.hotels.com/ho292636/casa-del-miele-susegana-italia/ 
    # http://www.expedia.it/Venezia-Hotel-Palazzo-Guardi.h1040663.Hotel-Information#reviews 
    # ... 

    for url in urls: 
     request = urllib2.Request(url.url) 
     if url.last_date == None: 
      now = datetime.now() 
      stamp = mktime(now.timetuple()) 
      url.last_date = format_date_time(stamp) 
      url.save() 

     request.add_header("If-Modified-Since", url.last_date) 

     try: 
      response = urllib2.urlopen(request) # Make the request 
      # some actions 
      now = datetime.now() 
      stamp = mktime(now.timetuple()) 
      url.last_date = format_date_time(stamp) 
      url.save() 
     except urllib2.HTTPError, err: 
      if err.code == 304: 
       print "nothing...." 
      else: 
       print "Error code:", err.code 
       pass 

Non capisco che cosa è andato storto. Qualcuno può aiutarmi?

+0

Hai considerato il fatto che una pagina Web potrebbe mentire sulle date? –

+0

@ princess-of-the-universe No, non l'ho considerato. Quindi cosa si può fare per verificare se una pagina è cambiata? Ho anche provato con 'hash' ma la pagina cambia ogni volta che la carica. – RoverDar

risposta

5

I server Web non sono tenuti a inviare un'intestazione 304 come risposta quando si invia un'intestazione 'If-Modified-Since'. Sono liberi di inviare un HTTP 200 e inviare di nuovo l'intera pagina.

L'invio di un 'If-Modified-Since' o 'If-None-Since' avvisa il server che si desidera una risposta memorizzata nella cache, se disponibile. È come inviare un header 'Accept-Encoding: gzip, deflate' - stai solo dicendo al server che accetteresti qualcosa, senza richiederlo.

+0

Grazie. Cosa posso usare per verificare se una pagina è cambiata? – RoverDar

+3

Il modo più semplice sarebbe quello di prendere le impronte digitali di ognuna con un hash MD5 e memorizzarle localmente per il confronto. Ma il problema è che, mentre il contenuto "principale" è invariato, il contenuto "ausiliario" è cambiato: tag annuncio diversi, "storie promosse", "link consigliati", "collegamenti partner" ecc. Anche un timestamp su la pagina butterà via l'MD5. –

+0

Potrebbe essere utile prendere solo per esempio? – RoverDar

0

Un buon modo per verificare se un sito restituisce 304 è utilizzare gli strumenti di google chromes dev. Per esempio. di seguito è riportato un esempio annotato di utilizzo di chrome sul sito Web di bls. Continuate a rinfrescare e vedrete che il server continua a restituire 304. Se forzate l'aggiornamento con Ctrl + F5 (Windows), vedrete che invece restituisce il codice di stato 200.

Potete usare questa tecnica sul vostro esempio per trovare se il server non restituisce 304 o se in qualche modo sono state formattate in modo errato le intestazioni delle richieste. A volte una pagina web ha una risorsa importata su di essa che non rispetta le intestazioni If e quindi restituisce 200 qualunque cosa tu faccia (se nessuna risorsa nella pagina non restituisce 304, l'intera pagina restituirà 200), ma a volte sei solo guardando una parte specifica di un sito Web e puoi imbrogliare caricando la risorsa direttamente e ignorando l'intero documento.

Problemi correlati