2013-03-04 121 views
7

在我的python應用程序中,我必須閱讀許多網頁才能收集數據。爲了減少http調用,我想只提取更改後的頁面。我的問題是,我的代碼總是告訴我,頁面已被更改(代碼200),但實際上它不是。檢測網頁是否發生變化

這是我的代碼:

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 

我不明白出了什麼問題。誰能幫我?

+0

您是否考慮過網頁可能必須說謊日期的事實? – 2013-03-04 17:25:46

+0

@宇宙公主不,我沒有考慮過這個。那麼可以做些什麼來檢查頁面是否發生了變化?我也嘗試'散列',但每次加載時頁面都會更改。 – RoverDar 2013-03-04 17:35:32

回答

5

當您發送'If-Modified-Since'標頭時,Web服務器不需要發送304標頭作爲響應。他們可以自由發送HTTP 200並再次發送整個頁面。

發送'If-Modified-Since'或'If-None-Since'會提醒服務器您希望緩存響應(如果可用)。這就像發送'Accept-Encoding:gzip,deflate'標題 - 你只是告訴服務器你會接受一些東西,而不需要它。

+0

謝謝。我可以使用什麼來檢查頁面是否發生了變化? – RoverDar 2013-03-04 17:36:23

+3

最簡單的方法是使用MD5散列對每個散列進行指紋,然後將其存儲在本地進行比較。但問題在於,雖然「主要」內容不變,但「輔助」內容已更改 - 不同的廣告標籤,「推廣故事」,「推薦鏈接」,「合作伙伴鏈接」等。甚至時間戳該頁面將拋出md5。 – 2013-03-04 17:48:04

+0

例如,僅採用可能會有所幫助。 – RoverDar 2013-03-04 17:56:50

0

檢查網站是否返回304的好方法是使用google chromes開發工具。例如。下面是在bls網站上使用chrome的註釋示例。繼續刷新,你會看到服務器不斷返回304.如果你用Ctrl + F5(窗口)強制刷新,你會看到它,而不是它返回狀態代碼200.

你可以使用這個技術在你的例子找到如果服務器沒有返回304,或者您以某種方式錯誤地格式化了請求標頭,則退出。有時一個網頁有一個資源導入到它,它不尊重If-標題,所以無論你做什麼都返回200(如果頁面上的任何資源沒有返回304,整個頁面將返回200),但有時你是隻查看網站的特定部分,您可以通過直接加載資源並繞過整個文檔來作弊。