2017-04-19 2 views
8

레일 캐쉬를 사용하여 Nokogiri 개체를 저장하려면 레일즈 5를 사용하고 있습니다. 레일 캐쉬를 사용하여 Nokogiri 개체를 저장하려면 어떻게해야합니까?

제가 설정/초기화/cache.rb이 만든 :

$cache = ActiveSupport::Cache::MemoryStore.new 

와 나는 같은 문서를 저장하고 싶었 :

$cache.fetch(url) { 
    result = get_content(url, headers, follow_redirects) 
} 

을하지만 난이 오류 받고 있어요 :

Error during processing: (TypeError) no _dump_data is defined for class Nokogiri::HTML::Document 
/Users/davea/.rvm/gems/ruby-2.4.0/gems/activesupport-5.0.2/lib/active_support/cache.rb:671:in `dump' 
/Users/davea/.rvm/gems/ruby-2.4.0/gems/activesupport-5.0.2/lib/active_support/cache.rb:671:in `dup_value!' 
/Users/davea/.rvm/gems/ruby-2.4.0/gems/activesupport-5.0.2/lib/active_support/cache/memory_store.rb:128:in `write_entry' 
/Users/davea/.rvm/gems/ruby-2.4.0/gems/activesupport-5.0.2/lib/active_support/cache.rb:398:in `block in write' 
/Users/davea/.rvm/gems/ruby-2.4.0/gems/activesupport-5.0.2/lib/active_support/cache.rb:562:in `block in instrument' 
/Users/davea/.rvm/gems/ruby-2.4.0/gems/activesupport-5.0.2/lib/active_support/notifications.rb:166:in `instrument' 
/Users/davea/.rvm/gems/ruby-2.4.0/gems/activesupport-5.0.2/lib/active_support/cache.rb:562:in `instrument' 
/Users/davea/.rvm/gems/ruby-2.4.0/gems/activesupport-5.0.2/lib/active_support/cache.rb:396:in `write' 
/Users/davea/.rvm/gems/ruby-2.4.0/gems/activesupport-5.0.2/lib/active_support/cache.rb:596:in `save_block_result_to_cache' 
/Users/davea/.rvm/gems/ruby-2.4.0/gems/activesupport-5.0.2/lib/active_support/cache.rb:300:in `fetch' 
/Users/davea/Documents/workspace/myproject/app/helpers/webpage_helper.rb:116:in `get_cached_content' 
/Users/davea/Documents/workspace/myproject/app/helpers/webpage_helper.rb:73:in `get_url' 
/Users/davea/Documents/workspace/myproject/app/services/abstract_my_object_finder_service.rb:29:in `process_data' 
/Users/davea/Documents/workspace/myproject/app/services/run_crawlers_service.rb:26:in `block (2 levels) in run_all_crawlers' 
/Users/davea/.rvm/gems/ruby-2.4.0/gems/concurrent-ruby-1.0.5/lib/concurrent/executor/ruby_thread_pool_executor.rb:348:in `run_task' 
/Users/davea/.rvm/gems/ruby-2.4.0/gems/concurrent-ruby-1.0.5/lib/concurrent/executor/ruby_thread_pool_executor.rb:337:in `block (3 levels) in create_worker' 
/Users/davea/.rvm/gems/ruby-2.4.0/gems/concurrent-ruby-1.0.5/lib/concurrent/executor/ruby_thread_pool_executor.rb:320:in `loop' 
/Users/davea/.rvm/gems/ruby-2.4.0/gems/concurrent-ruby-1.0.5/lib/concurrent/executor/ruby_thread_pool_executor.rb:320:in `block (2 levels) in create_worker' 
/Users/davea/.rvm/gems/ruby-2.4.0/gems/concurrent-ruby-1.0.5/lib/concurrent/executor/ruby_thread_pool_executor.rb:319:in `catch' 
/Users/davea/.rvm/gems/ruby-2.4.0/gems/concurrent-ruby-1.0.5/lib/concurrent/executor/ruby_thread_pool_executor.rb:319:in `block in create_worker' 

캐시에 이러한 개체를 저장하려면 무엇을해야합니까?

+1

분명히 그렇지 않습니다. 캐시는 문자열 저장에 좋습니다. –

+1

왜 개체를 저장 하시겠습니까? Nokogiri를 사용하여 HTML 또는 XML에서 긁어 낸 정보가 포함 된 직렬화 된 해시 또는 배열을 저장합니다. 개체를 저장해야하는 경우 메모 작성을 살펴보십시오. –

+1

이것에 대해 더 생각해 보면, 메모리 캐시는 즉시 액세스해야하는 경우에 유용하지만 컴퓨터가 다운 된 경우 신속하게 다시 만들 수 있습니다. Nokogiri를 사용하고 있다면, 페이지를 긁어 내고있는 것을 알 수있는 확률이 높습니다. 페이지를로드하는 중임을 의미합니다.로드, 구문 분석, 긁기 프로세스로 원하지 않는 대기 시간이 추가됩니다 (그러므로 캐시를 사용하는 아이디어) 대신 (메타) 데이터를 수집하여 영구적으로 사용할 수있는 데이터베이스에 저장해야합니다. DBM은 내부적으로 캐시됩니다. 메모리 내 캐시만큼 빠르지는 않지만 요청시 또는 앱 시작시 재 작성하는 것보다 낫습니다. –

답변

2

사용자 노코 기리의 직렬화 기능 :

$cache = ActiveSupport::Cache::MemoryStore.new 
noko_object = Nokogiri::HTML::Document.new 

serial = noko_object.serialize 
$cache.write(url, serial) 
// Serialized Nokogiri document is now in store at the URL key. 
result = $cache.read(url) 

noko_object = Nokogiri::HTML::Document.new(result) 
// noko_object is now the original document again :) 

Check out the documentation here for more information.

+0

감사하지만 "캐시에 직렬 객체 저장"에 대한 코드는 무엇입니까? 나는 "$ cache.fetch (url) {"의 본문이 물건을 저장하고 검색하는 것을 처리 할 것이라고 생각 했습니까? – Dave

+1

당신은 그곳에 아무 것도 필요로하지 않을 수도 있습니다. 건너 뛰기 만하면, 찾고있는 것은'serialize'입니다. –

+0

네,하지만 "get_content"가 Nokogiri Document를 반환하기 때문에 (여전히 슬프게도 메소드를 변경할 수 없기 때문에) 실패했습니다. 따라서 외부 "$ cache.fetch"가 나와있는 오류로 인해 실패하게됩니다. 내가 아무것도 알지 못한다고 가정하면 (기본적으로 사실 임) 나와 저를 위해 철자를 기입하십시오. 내 Rails 캐시를 사용하는 Nokogiri 문서를 반환하는 메소드는 어떻게 작성합니까? – Dave

3

xml을 개체가 아닌 문자열로 저장하고 캐시에서 꺼내면 구문 ​​분석하십시오.

편집 : 의견을 응답 : 응답이

캐시 대신이

nokogiri_object.to_xml 

Edit2가 코멘트합니다. 이 라인을 따라 뭔가. 좀 더 구체적인 도움이 필요하면 더 많은 코드를 게시해야합니다.

nokogiri_object = Nokogiri::XML(cache.fetch('xml_doc')) 

Edit3 : '감사합니다.하지만'캐시에 직렬화 된 객체 저장 '에 대한 코드는 무엇입니까? 나는 "$ cache.fetch (url) {"의 본문이 저장을 처리 한 다음 물건을 검색 할 것이라고 생각했습니다. "

cache.write('url', xml_or_serialized_nokogiri_string) 
+0

몇 가지 코드 예제를 살펴 보겠습니다. – Dave

+0

안녕하세요, 이걸 다시 Nokogiri 의사에게 보내 주시겠습니까? 내 요구 사항은 Nokogiri 문서를 저장하고 검색 할 수있는 캐시 방법을 호출해야한다는 것입니다. 그 중간에 어떤 중간 형태를 취하면 괜찮습니다. 그러나 최종 결과는 Nokogiri 문서 여야합니다. 나는 당신이 제공 한 것과 함께 이것을 달성하는 방법을 아직도 보지 못하고있다. – Dave

+0

완료! 내 질문에 내 코드를 참조하십시오. get_cached_data 메소드는 "$ cache.fetch (url) {"로 코드 strting을 포함합니다. "get_content (url, headers, follow_redirects)"메서드는 Nokogiri 문서를 반환합니다. 그렇다면 그 결과를 XML로 변환 한 다음 다시 문자열로 변환합니까? – Dave