基本上我正在尝试运行一些代码(Python 3.2),如果网站上的值发生变化,否则稍等一会儿再检查一下.
首先,我想我可以将值保存在变量中,并将其与下次运行脚本时获取的新值进行比较.但是,当脚本再次运行并初始化该变量时,值会被覆盖,这很快就会遇到问题.
那么我尝试将网页的html保存为文件,然后将其与下次运行脚本时调用的html进行比较.那里没有运气,因为即使没有变化,它仍然会出现错误.
接下来是腌制网页,然后尝试将其与html进行比较.有趣的是,这在脚本中都不起作用.但是,如果我在脚本运行后键入file = pickle.load(打开('D:\ Download\htmlString.p','rb')),然后输入file == html,则在没有脚本时显示True任何变化.
我有点困惑的是,为什么它在脚本运行时不起作用,但如果我这样做,它会显示正确的答案.
编辑:感谢你们迄今为止的回复.我的问题并不是关于其他方法(尽管学习更多方法来完成任务总是好的!)而是为什么下面的代码在作为脚本运行时不起作用,但如果我在脚本运行后在提示符处重新加载pickle对象,然后针对html测试它,如果没有任何更改,它将返回True.
try:
file = pickle.load( open( 'D:\\Download\\htmlString.p', 'rb'))
if pickle.load( open( 'D:\\Download\\htmlString.p', 'rb')) == htmlString:
print("Values haven't changed!")
sys.exit(0)
else:
pickle.dump( htmlString, open( 'D:\\Download\\htmlString.p', "wb" ) )
print('Saving')
except:
pickle.dump( htmlString, open( 'D:\\Download\\htmlString.p', "wb" ) )
print('ERROR')
Run Code Online (Sandbox Code Playgroud)
编辑:我没有意识到你只是在寻找你的脚本问题.这就是我认为的问题,然后是我原来的答案,它解决了你试图解决的更大问题的另一种方法.
你的脚本是使用一揽子except
声明的危险的一个很好的例子:你抓住了一切.包括,在这种情况下,你的sys.exit(0)
.
我假设你在try
那里阻止那里D:\Download\htmlString.p
尚不存在的情况.调用该错误IOError
,您可以专门捕获它except IOError:
以下是您的脚本以及之前的一些代码,以便解决您的except
问题:
import sys
import pickle
import urllib2
request = urllib2.Request('http://www.iana.org/domains/example/')
response = urllib2.urlopen(request) # Make the request
htmlString = response.read()
try:
file = pickle.load( open( 'D:\\Download\\htmlString.p', 'rb'))
if file == htmlString:
print("Values haven't changed!")
sys.exit(0)
else:
pickle.dump( htmlString, open( 'D:\\Download\\htmlString.p', "wb" ) )
print('Saving')
except IOError:
pickle.dump( htmlString, open( 'D:\\Download\\htmlString.p', "wb" ) )
print('Created new file.')
Run Code Online (Sandbox Code Playgroud)
作为旁注,您可以考虑使用os.path
您的文件路径 - 它将帮助以后想要在另一个平台上使用您的脚本的任何人,并且它可以为您节省丑陋的双反斜杠.
编辑2:根据您的特定URL进行调整.
该页面上的广告有一个动态生成的编号,随着每个页面加载而变化.在所有内容之后它接近结尾,所以我们可以在那一点拆分HTML字符串并取上半部分,丢弃带有动态数字的部分.
import sys
import pickle
import urllib2
request = urllib2.Request('http://ecal.forexpros.com/e_cal.php?duration=weekly')
response = urllib2.urlopen(request) # Make the request
# Grab everything before the dynabic double-click link
htmlString = response.read().split('<iframe src="http://fls.doubleclick')[0]
try:
file = pickle.load( open( 'D:\\Download\\htmlString.p', 'r'))
if pickle.load( open( 'D:\\Download\\htmlString.p', 'r')) == htmlString:
print("Values haven't changed!")
sys.exit(0)
else:
pickle.dump( htmlString, open( 'D:\\Download\\htmlString.p', "w" ) )
print('Saving')
except IOError:
pickle.dump( htmlString, open( 'D:\\Download\\htmlString.p', "w" ) )
print('Created new file.')
Run Code Online (Sandbox Code Playgroud)
如果这很重要,那么您的字符串就不再是有效的HTML文档.如果是,您可能只是删除该行或其他东西.这可能是一种更优雅的方式,也许用正则表达式删除数字 - 但这至少可以满足你的问题.
原始答案 - 解决您问题的另一种方法.
响应标头从Web服务器看起来是什么样的?HTTP指定了一个Last-Modified
可用于检查内容是否已更改的属性(假设服务器说明了事实).HEAD
正如Uku在答案中所表明的那样,请使用此请求.如果你想节省带宽并且对你正在轮询的服务器很好.
而且还有一个If-Modified-Since
标题听起来像你可能正在寻找的.
如果我们将它们组合在一起,你可能会想出这样的东西:
import sys
import os.path
import urllib2
url = 'http://www.iana.org/domains/example/'
saved_time_file = 'last time check.txt'
request = urllib2.Request(url)
if os.path.exists(saved_time_file):
""" If we've previously stored a time, get it and add it to the request"""
last_time = open(saved_time_file, 'r').read()
request.add_header("If-Modified-Since", last_time)
try:
response = urllib2.urlopen(request) # Make the request
except urllib2.HTTPError, err:
if err.code == 304:
print "Nothing new."
sys.exit(0)
raise # some other http error (like 404 not found etc); re-raise it.
last_modified = response.info().get('Last-Modified', False)
if last_modified:
open(saved_time_file, 'w').write(last_modified)
else:
print("Server did not provide a last-modified property. Continuing...")
"""
Alternately, you could save the current time in HTTP-date format here:
http://www.w3.org/Protocols/rfc2616/rfc2616-sec3.html#sec3.3
This might work for some servers that don't provide Last-Modified, but do
respect If-Modified-Since.
"""
"""
You should get here if the server won't confirm the content is old.
Hopefully, that means it's new.
HTML should be in response.read().
"""
Run Code Online (Sandbox Code Playgroud)
另请参阅Stii撰写的这篇博文,其中可能会提供一些灵感.我不知道ETags
将它们放在我的例子中,但他的代码也检查了它们.
归档时间: |
|
查看次数: |
16619 次 |
最近记录: |