質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

90.52%

  • Ruby on Rails 4

    2534questions

    Ruby on Rails4はRubyによって書かれたオープンソースのウェブフレームワークです。 Ruby on Railsは「設定より規約」の原則に従っており、効率的に作業を行うために再開発を行う必要をなくしてくれます。

rubyクローラー データをmysql保存時のエラー解決方法について

受付中

回答 0

投稿

  • 評価
  • クリップ 1
  • VIEW 477

hiroyuki24

score 2

前提・実現したいこと

ruby初心者でクローラーを作成してます。
その中でWebから取得した情報をmysqlに登録する箇所でエラーが発生しました。

発生している問題・エラーメッセージ

/Users/hiroyuki/.rbenv/versions/2.1.3/lib/ruby/site_ruby/2.1.0/rubygems/core_ext/kernel_require.rb:55:in `require': /Users/hiroyuki/.rbenv/versions/2.1.3/lib/ruby/gems/2.1.0/gems/anemone-0.7.2/lib/anemone/storage/mysql.rb:105: can't find string "SQL" anywhere before EOF (SyntaxError)
/Users/hiroyuki/.rbenv/versions/2.1.3/lib/ruby/gems/2.1.0/gems/anemone-0.7.2/lib/anemone/storage/mysql.rb:82: syntax error, unexpected end-of-input, expecting tSTRING_CONTENT or tSTRING_DBEG or tSTRING_DVAR or tSTRING_END
    from /Users/hiroyuki/.rbenv/versions/2.1.3/lib/ruby/site_ruby/2.1.0/rubygems/core_ext/kernel_require.rb:55:in `require'
    from /Users/hiroyuki/.rbenv/versions/2.1.3/lib/ruby/gems/2.1.0/gems/anemone-0.7.2/lib/anemone/storage.rb:44:in `MySQL'
    from anemone-mysql.rb:8:in `<main>'

該当のソースコード

require 'anemone'

urls = []
urls.push("http://www.yahoo.co.jp")

opts = {
:storage => Anemone::Storage::MySQL(),
:depth_limit => 0
}

Anemone.crawl(urls, opts) do |anemone|
anemone.on_every_page do |page|
puts page.url
puts page.doc.xpath("//title/text()").to_s if page.doc
end
end

試したこと

補足情報(言語/FW/ツール等のバージョンなど)

関係ファイルのソースコードを下記に記載します。

mysql.rb

begin
require 'mysql2'
rescue LoadError
puts "You need the mysql2 gem to use Anemone::Storage::MySQL"
exit
end

module Anemone
module Storage
class MySQL

def initialize(opts = {})
host = opts[:host] || 'localhost'
username = opts[:username] || 'crawler'
password = opts[:password] || 'anemone_pass'
database = opts[:database] || 'anemone'
@db = Mysql2::Client.new(:host => host, :username => username, :password => password, :database => database)
create_schema
end

def [](url)
value = @db.query("SELECT data FROM anemone_storage WHERE page_key = '#{get_hash_value(url)}'").first['data']
if value
Marshal.load(value)
end
end

def []=(url, value)
data = Marshal.dump(value)
key = get_hash_value(url)
if has_key?(url)
@db.query("UPDATE anemone_storage SET page_data = '#{data}' WHERE page_key = '#{key}'")
else
@db.query("INSERT INTO anemone_storage (page_key, page_data) VALUES('#{key}', '#{data}')")
end
end

def delete(url)
page = self[url]
@db.query("DELETE FROM anemone_storage WHERE page_key = '#{get_hash_value(url)}'")
page
end

def each
@db.execute("SELECT page_key, page_data FROM anemone_storage ORDER BY id") do |row|
value = Marshal.load(row[1])
yield row[0], value
end
end

def merge!(hash)
hash.each { |key, value| self[key] = value }
self
end

def size
@db.query('SELECT COUNT(*) FROM anemone_storage')
end

def keys
@db.query("SELECT page_key FROM anemone_storage ORDER BY id").map{|t| t[0]}
end

def has_key?(url)
key = get_hash_value(url)
result = @db.query("SELECT count(id) FROM anemone_storage WHERE page_key = '#{key}'")
if result.first['count(id)'] > 0
return true
else
return false
end
end

def close
@db.close
end

private
def create_schema
@db.query <<-SQL
create table if not exists anemone_storage (
id int(11) NOT NULL auto_increment,
page_key varchar(255),
page_data BLOB,
PRIMARY KEY (id),
key (page_key)
) DEFAULT CHARSET=utf8;SQL
end

def load_page(hash)
BINARY_FIELDS.each do |field|
hash[field] = hash[field].to_s
end
Page.from_hash(hash)
end

def get_hash_value(key)
Digest::SHA1.hexdigest(key)
end
end
end
end

storage.rb

module Anemone
module Storage

def self.Hash(*args)
hash = Hash.new(*args)

 add close method for compatibility with Storage::Base

class << hash; def close; end; end
hash
end

def self.PStore(*args)
require 'anemone/storage/pstore'
self::PStore.new(*args)
end

def self.TokyoCabinet(file = 'anemone.tch')
require 'anemone/storage/tokyo_cabinet'
self::TokyoCabinet.new(file)
end

def self.KyotoCabinet(file = 'anemone.kch')
require 'anemone/storage/kyoto_cabinet'
self::KyotoCabinet.new(file)
end

def self.MongoDB(mongo_db = nil, collection_name = 'pages')
require 'anemone/storage/mongodb'
mongo_db ||= Mongo::Connection.new.db('anemone')
raise "First argument must be an instance of Mongo::DB" unless mongo_db.is_a?(Mongo::DB)
self::MongoDB.new(mongo_db, collection_name)
end

def self.Redis(opts = {})
require 'anemone/storage/redis'
self::Redis.new(opts)
end

def self.SQLite3(file = 'anemone.db')
require 'anemone/storage/sqlite3'
self::SQLite3.new(file)
end

def self.MySQL(opts = {})
require 'anemone/storage/mysql'
self::MySQL.new(opts)
end

end
end

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

まだ回答がついていません

同じタグがついた質問を見る

  • Ruby on Rails 4

    2534questions

    Ruby on Rails4はRubyによって書かれたオープンソースのウェブフレームワークです。 Ruby on Railsは「設定より規約」の原則に従っており、効率的に作業を行うために再開発を行う必要をなくしてくれます。