2013-03-04 14 views
7

W mojej aplikacji Pythona muszę przeczytać wiele stron internetowych, aby zebrać dane. Aby zmniejszyć liczbę wywołań http, chciałbym pobrać tylko zmienione strony. Mój problem polega na tym, że mój kod zawsze mówi mi, że strony zostały zmienione (kod 200), ale w rzeczywistości tak nie jest.wykryć, czy strona internetowa została zmieniona

To jest mój kod:

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 

ja nie rozumiem, co poszło nie tak. Czy ktoś może mi pomóc?

+0

Czy wziął pod uwagę fakt, że strona internetowa może zawierać informacje dotyczące dat? –

+0

@ księżniczka-wszechświata Nie, nie zastanawiałem się nad tym. Co więc można zrobić, aby sprawdzić, czy strona się zmieniła? Próbowałem również z "hash", ale strona zmienia się przy każdym załadowaniu. – RoverDar

Odpowiedz

5

Serwery WWW nie muszą wysyłać nagłówka 304 jako odpowiedzi podczas wysyłania nagłówka "If-Modified-Since". Mogą wysłać HTTP 200 i ponownie wysłać całą stronę.

Wysłanie komunikatu "Jeśli zmodyfikowano-od" lub "Jeśli-brak-od" spowoduje, że serwer powiadomi serwer, że ma być buforowana odpowiedź, jeśli jest dostępna. To tak, jakby wysłać nagłówek "Accept-Encoding: gzip, deflate" - po prostu mówisz serwerowi, że coś zaakceptujesz, nie wymagając tego.

+0

Dzięki. Co mogę użyć, aby sprawdzić, czy strona się zmieniła? – RoverDar

+3

Najprostszym sposobem jest pobranie odcisków palców każdego z nich za pomocą skrótu MD5 i zapisanie ich lokalnie w celu porównania. ALE problem polega na tym, że podczas gdy "główna" zawartość pozostaje niezmieniona, zmieniła się "pomocnicza" treść - różne tagi reklamowe, "promowane historie", "zalecane linki", "partnerskie linki" itd. Nawet znacznik czasu na strona wyrzuci md5. –

+0

Może być pomocne, aby na przykład wziąć tylko ? – RoverDar

0

Dobrym sposobem na sprawdzenie, czy strona zwróci 304, jest użycie narzędzi deweloperskich google chromes. Na przykład. poniżej znajduje się przykładowy opis używania chrome na stronie internetowej bls. Odświeżaj, a zobaczysz, że serwer powraca do stanu 304. Jeśli wymusisz odświeżenie za pomocą Ctrl + F5 (Windows), zobaczysz, że zamiast tego zwraca kod stanu 200.

Możesz użyć tej techniki na swoim przykładzie, aby znaleźć out, jeśli serwer nie zwraca 304 lub nieprawidłowo sformatował nagłówki żądania w jakiś sposób. Czasami strona internetowa ma zaimportowany zasób, który nie respektuje nagłówków If, a więc zwraca 200 niezależnie od tego, co robisz (jeśli dowolny zasób na stronie nie zwróci 304, cała strona zwróci 200), ale czasami jesteś Patrząc tylko na określoną część strony internetowej, możesz oszukiwać, ładując zasób bezpośrednio i pomijając cały dokument.

Powiązane problemy