क्या urllib2 का उपयोग करते समय चीजों को कैश करने का कोई आसान तरीका है जो मैं देख रहा हूं, या मुझे अपना खुद का रोल करना है?urllib2 में कैशिंग?
उत्तर
आप इस तरह के रूप में एक डेकोरेटर समारोह इस्तेमाल कर सकते हैं:
class cache(object):
def __init__(self, fun):
self.fun = fun
self.cache = {}
def __call__(self, *args, **kwargs):
key = str(args) + str(kwargs)
try:
return self.cache[key]
except KeyError:
self.cache[key] = rval = self.fun(*args, **kwargs)
return rval
except TypeError: # incase key isn't a valid key - don't cache
return self.fun(*args, **kwargs)
और की तर्ज पर एक समारोह को परिभाषित:
@cache
def get_url_src(url):
return urllib.urlopen(url).read()
यह मानते हुए है आप HTTP कैश नियंत्रण पर ध्यान नहीं कर रहे हैं, लेकिन बस आवेदन की अवधि के लिए पृष्ठ को कैश करना चाहते हैं
यह ActiveState अजगर नुस्खा उपयोगी हो सकता है: http://code.activestate.com/recipes/491261/
आप एक थोड़ा कम स्तर, httplib2 (https://github.com/httplib2/httplib2) एक उत्कृष्ट HTTP पुस्तकालय कि कैशिंग कार्यक्षमता भी शामिल है पर काम कर रहे कोई आपत्ति नहीं है।
कृपया ठीक टाइपो: httlib2 -> httplib2 – tzot
बस याद रखें कि आप अन्य योजनाओं (फ़ाइल, FTP के लिए समर्थन खो देंगे, .. ।) httplib2 का उपयोग करते समय। –
मैं कुछ इसी तरह की तलाश में था, और "Recipe 491261: Caching and throttling for urllib2" पर आया जो डैनिवो पोस्ट किया गया। समस्या यह है कि मैं वास्तव में कैशिंग कोड को नापसंद करता हूं (बहुत सारे डुप्लिकेशंस, os.path.join का उपयोग करने के बजाय फ़ाइल पथों में मैन्युअल रूप से शामिल होने के बहुत सारे, staticmethods, गैर बहुत पीईपी 8'आईह, और अन्य चीजों से बचने की कोशिश करते हैं)
कोड थोड़ा अच्छा है (मेरी राय में वैसे भी) और कुछ अतिरिक्त जोड़ों के साथ कार्यात्मक रूप से वही है - मुख्य रूप से "रिकैच" विधि (उदाहरण उपयोग can be seem here, या कोड के अंत में if __name__ == "__main__":
अनुभाग में)।
नवीनतम संस्करण http://github.com/dbr/tvdb_api/blob/master/cache.py में पाया जा सकता है, और मैं भावी पीढ़ी के लिए यहाँ यह चस्पा करेंगे (अपने आवेदन के साथ विशिष्ट हेडर हटाया):
#!/usr/bin/env python
"""
urllib2 caching handler
Modified from http://code.activestate.com/recipes/491261/ by dbr
"""
import os
import time
import httplib
import urllib2
import StringIO
from hashlib import md5
def calculate_cache_path(cache_location, url):
"""Checks if [cache_location]/[hash_of_url].headers and .body exist
"""
thumb = md5(url).hexdigest()
header = os.path.join(cache_location, thumb + ".headers")
body = os.path.join(cache_location, thumb + ".body")
return header, body
def check_cache_time(path, max_age):
"""Checks if a file has been created/modified in the [last max_age] seconds.
False means the file is too old (or doesn't exist), True means it is
up-to-date and valid"""
if not os.path.isfile(path):
return False
cache_modified_time = os.stat(path).st_mtime
time_now = time.time()
if cache_modified_time < time_now - max_age:
# Cache is old
return False
else:
return True
def exists_in_cache(cache_location, url, max_age):
"""Returns if header AND body cache file exist (and are up-to-date)"""
hpath, bpath = calculate_cache_path(cache_location, url)
if os.path.exists(hpath) and os.path.exists(bpath):
return(
check_cache_time(hpath, max_age)
and check_cache_time(bpath, max_age)
)
else:
# File does not exist
return False
def store_in_cache(cache_location, url, response):
"""Tries to store response in cache."""
hpath, bpath = calculate_cache_path(cache_location, url)
try:
outf = open(hpath, "w")
headers = str(response.info())
outf.write(headers)
outf.close()
outf = open(bpath, "w")
outf.write(response.read())
outf.close()
except IOError:
return True
else:
return False
class CacheHandler(urllib2.BaseHandler):
"""Stores responses in a persistant on-disk cache.
If a subsequent GET request is made for the same URL, the stored
response is returned, saving time, resources and bandwidth
"""
def __init__(self, cache_location, max_age = 21600):
"""The location of the cache directory"""
self.max_age = max_age
self.cache_location = cache_location
if not os.path.exists(self.cache_location):
os.mkdir(self.cache_location)
def default_open(self, request):
"""Handles GET requests, if the response is cached it returns it
"""
if request.get_method() is not "GET":
return None # let the next handler try to handle the request
if exists_in_cache(
self.cache_location, request.get_full_url(), self.max_age
):
return CachedResponse(
self.cache_location,
request.get_full_url(),
set_cache_header = True
)
else:
return None
def http_response(self, request, response):
"""Gets a HTTP response, if it was a GET request and the status code
starts with 2 (200 OK etc) it caches it and returns a CachedResponse
"""
if (request.get_method() == "GET"
and str(response.code).startswith("2")
):
if 'x-local-cache' not in response.info():
# Response is not cached
set_cache_header = store_in_cache(
self.cache_location,
request.get_full_url(),
response
)
else:
set_cache_header = True
#end if x-cache in response
return CachedResponse(
self.cache_location,
request.get_full_url(),
set_cache_header = set_cache_header
)
else:
return response
class CachedResponse(StringIO.StringIO):
"""An urllib2.response-like object for cached responses.
To determine if a response is cached or coming directly from
the network, check the x-local-cache header rather than the object type.
"""
def __init__(self, cache_location, url, set_cache_header=True):
self.cache_location = cache_location
hpath, bpath = calculate_cache_path(cache_location, url)
StringIO.StringIO.__init__(self, file(bpath).read())
self.url = url
self.code = 200
self.msg = "OK"
headerbuf = file(hpath).read()
if set_cache_header:
headerbuf += "x-local-cache: %s\r\n" % (bpath)
self.headers = httplib.HTTPMessage(StringIO.StringIO(headerbuf))
def info(self):
"""Returns headers
"""
return self.headers
def geturl(self):
"""Returns original URL
"""
return self.url
def recache(self):
new_request = urllib2.urlopen(self.url)
set_cache_header = store_in_cache(
self.cache_location,
new_request.url,
new_request
)
CachedResponse.__init__(self, self.cache_location, self.url, True)
if __name__ == "__main__":
def main():
"""Quick test/example of CacheHandler"""
opener = urllib2.build_opener(CacheHandler("/tmp/"))
response = opener.open("http://google.com")
print response.headers
print "Response:", response.read()
response.recache()
print response.headers
print "After recache:", response.read()
main()
याहू डेवलपर नेटवर्क पर यह लेख - http://developer.yahoo.com/python/python-caching.html - बताता है कि कैसे करने के लिए कैश http कॉल या तो स्मृति या डिस्क के लिए urllib के माध्यम से किया जाता है।
मुझे हमेशा प्रेजिपीप्लिब 2 का उपयोग करने के बीच फाड़ा गया है, जो HTTP कैशिंग और प्रमाणीकरण को संभालने का ठोस काम करता है, और urllib2, जो stdlib में है, में एक एक्स्टेंसिबल इंटरफ़ेस है, और HTTP प्रॉक्सी सर्वर का समर्थन करता है।
ActiveState recipe urllib2 पर कैशिंग समर्थन जोड़ने शुरू होता है, लेकिन केवल एक बहुत ही प्राचीन फैशन में। यह भंडारण तंत्र में विस्तारशीलता की अनुमति देने में विफल रहता है, फ़ाइल-सिस्टम-समर्थित स्टोरेज को हार्ड-कोडिंग करता है। यह HTTP कैश हेडर का भी सम्मान नहीं करता है।
fansplib2 कैशिंग और urllib2 एक्स्टेंसिबिलिटी की सर्वोत्तम सुविधाओं को एक साथ लाने के प्रयास में, मैंने एक्टिवस्टेट रेसिपी को उसी कैशिंग कार्यक्षमता को कार्यान्वित करने के लिए अनुकूलित किया है जैसा कि httplib2 में मिलता है। मॉड्यूल jaraco.net में jaraco.net.http.caching के रूप में है। यह लिंक मॉड्यूल को इंगित करता है क्योंकि यह इस लेखन के समय मौजूद है। हालांकि वह मॉड्यूल वर्तमान में बड़े jaraco.net पैकेज का हिस्सा है, लेकिन इसमें कोई अंतर-पैकेज निर्भरता नहीं है, इसलिए मॉड्यूल को खींचने और अपनी परियोजनाओं में इसका उपयोग करने के लिए स्वतंत्र महसूस करें।
वैकल्पिक रूप से, यदि आपके पास पाइथन 2.6 या बाद में है, तो आप easy_install jaraco.net>=1.3
कर सकते हैं और फिर caching.quick_test()
में कोड जैसे कुछ के साथ कैशिंग हैंडलर का उपयोग कर सकते हैं।
"""Quick test/example of CacheHandler"""
import logging
import urllib2
from httplib2 import FileCache
from jaraco.net.http.caching import CacheHandler
logging.basicConfig(level=logging.DEBUG)
store = FileCache(".cache")
opener = urllib2.build_opener(CacheHandler(store))
urllib2.install_opener(opener)
response = opener.open("http://www.google.com/")
print response.headers
print "Response:", response.read()[:100], '...\n'
response.reload(store)
print response.headers
print "After reload:", response.read()[:100], '...\n'
ध्यान दें कि jaraco.util.http।कैशिंग कैश के लिए बैकिंग स्टोर के लिए एक विनिर्देश प्रदान नहीं करता है, बल्कि इसके बजाय httplib2 द्वारा उपयोग किए गए इंटरफ़ेस का पालन करता है। इस कारण से, httplib2.FileCache सीधे urllib2 और कैशहैंडलर के साथ उपयोग किया जा सकता है। इसके अलावा, httplib2 के लिए डिज़ाइन किए गए अन्य बैकिंग कैश कैशहैंडलर द्वारा प्रयोग योग्य होना चाहिए।
@dbr: आप भी जोड़ना पड़ सकता है https साथ प्रतिक्रियाओं कैशिंग:
def https_response(self, request, response):
return self.http_response(request,response)
- 1. urllib2
- 2. urllib2
- 3. urllib2
- 4. urllib2
- 5. urllib2.URLError
- 6. HTTPS urllib2
- 7. urllib2 स्ट्रिंग
- 8. पाइथन urllib2
- 9. urllib2.urlopen
- 10. कैशिंग
- 11. कैशिंग
- 12. कैशिंग
- 13. urllib2 और json
- 14. पायथन URLLib/URLLib2 पोस्ट
- 15. पायथन और urllib2
- 16. पायथन urllib2: यूआरएल
- 17. कुकीज़ के साथ urllib2
- 18. पायथन: Urllib2 और OpenCV
- 19. बताएँ urllib2 कस्टम DNS
- 20. पायथन urllib2 त्रुटियां
- 21. पायथन - urllib2 और cookielib
- 22. अजगर urllib2 urlopen प्रतिक्रिया
- 23. पायथन urllib2 प्रतिक्रिया शीर्षलेख
- 24. हैंडलिंग आरएसएस अजगर/urllib2
- 25. backbone.js में कैशिंग संग्रह?
- 26. एंड्रॉइड वेबव्यू में कैशिंग
- 27. लिनक्स में DNS कैशिंग
- 28. grails में कैशिंग डेटा
- 29. पायथन - urllib2 में अप्रशिक्षित प्रकार त्रुटि
- 30. एक PHP कैशिंग तकनीक का चयन: फाइलों में उत्पादन कैशिंग बनाम opcode कैशिंग
मैंने इसे कार्यान्वित किया, लेकिन एक स्क्लाइट बैकएंड और अनुकूलन कैश अवधि के साथ। धन्यवाद :) – Yuvi
@Yuvi इसे कहीं पोस्ट करना अच्छा होगा :) –
यह तब तक कैश संसाधनों के लिए मान्य नहीं है जब तक कि आप आरएफसी में निर्देशों के अनुसार अपने शीर्षलेखों की जांच न करें। या शायद आप इस समाधान का सुझाव दे रहे हैं जैसे किसी एक वेब पेज के एक दृश्य को इकट्ठा करना, और बार-बार रीलोड पर उपयोग के लिए नहीं? –