检测网页是否更改

8 投票
2 回答
9662 浏览
提问于 2025-04-17 17:53

在我的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

我不明白哪里出了问题。有人能帮我吗?

2 个回答

0

想要检查一个网站是否返回304状态码,一个好方法是使用谷歌浏览器的开发者工具。例如,下面是一个在bls网站上使用Chrome的示例。你可以不断刷新页面,你会发现服务器一直返回304状态码。如果你按下Ctrl+F5(在Windows上),强制刷新页面,你会看到它返回的是200状态码。

你可以用这种方法在你的例子中查看服务器是否没有返回304,或者你的请求头格式是否有问题。有时候,一个网页上会引入一些资源,这些资源不遵循If-开头的请求头,因此无论你怎么做,它都会返回200状态码(如果页面上的任何资源不返回304,整个页面就会返回200)。但有时候你只是在查看网站的某个特定部分,你可以通过直接加载这个资源来“作弊”,绕过整个文档。

5

当你发送一个'If-Modified-Since'的请求头时,网络服务器并不一定要返回304这个状态码。它们可以选择返回HTTP 200,并把整个页面重新发送给你。

发送'If-Modified-Since'或'If-None-Since'的意思是告诉服务器,如果有缓存的内容可以用的话,希望能得到这个缓存的响应。这就像你发送一个'Accept-Encoding: gzip, deflate'的请求头——你只是告诉服务器你可以接受这些格式的内容,并不是强制要求它这样做。

撰写回答