Python 检测网页是否已更改

Python 检测网页是否已更改,python,web,screen-scraping,if-modified-since,Python,Web,Screen Scraping,If Modified Since,在我的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

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

我不明白出了什么问题。有人能帮我吗?

当您发送“If Modified-Since”标头时,Web服务器不需要发送304标头作为响应。他们可以免费发送HTTP 200并再次发送整个页面


发送“If Modified Since”或“If None Since”会提醒服务器您希望缓存响应(如果可用)。这就像发送一个“Accept Encoding:gzip,deflate”头——你只是告诉服务器你将接受某个东西,而不是要求它。

检查站点是否返回304的一个好方法是使用谷歌chromes开发工具。例如,下面是在bls网站上使用chrome的注释示例。保持刷新,您将看到服务器不断返回304。如果使用Ctrl+F5(windows)强制刷新,您将看到它返回状态代码200

您可以在示例中使用此技术来确定服务器是否返回304,或者您是否以某种方式错误地格式化了请求头。有时,一个网页上导入了一个不尊重If-header的资源,因此无论你做什么,它都会返回200(如果页面上的任何资源不返回304,整个页面将返回200),但有时您只查看网站的特定部分,您可以通过直接加载资源并绕过整个文档来作弊


你有没有想过网页可能会对日期撒谎?“宇宙公主”不,我没有考虑过这个问题。那么,如何检查页面是否已更改?我也尝试过“散列”,但每次加载时页面都会更改。谢谢。我可以使用什么来检查页面是否已更改?最简单的方法是使用MD5哈希对每个页面进行指纹识别,并将其存储在本地以进行比较。但问题是,虽然“主要”内容没有变化,“辅助”内容也发生了变化——不同的广告标签、“宣传故事”、“推荐链接”,“伙伴链接”等,甚至页面上的一个时间戳都会抛出MD5。这可能是有帮助的,仅举个例子。在我的例子中,我不能考虑整个页面,而只考虑我想要收集数据的部分(如评论部分)。在第一部分中,我计算散列并将其存储在本地。是吗?是的。创建一个带有“url | timestamp | u accessed | hash”的数据库,然后查询最近访问的timestamp | u的hash。如果不一样,你就有了新的内容。如果您只使用这5个站点,则可以使用BeautifulSoup了解如何仅隔离所需的部分。