2013-03-04 101 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),但有时你是只查看网站的特定部分,您可以通过直接加载资源并绕过整个文档来作弊。

相关问题