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

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

ただいまの
回答率

90.47%

  • Ruby

    7938questions

    Rubyはプログラミング言語のひとつで、オープンソース、オブジェクト指向のプログラミング開発に対応しています。

スクレイピングで取得したデータの一部しかcsvに書き込めません

解決済

回答 2

投稿

  • 評価
  • クリップ 0
  • VIEW 1,190

beij

score 10

Amazonのレビュー欄のデータ(レビューの本文や評価など)をスクレイピングすることには成功したのですが、それをcsvに書き込もうとしても一部しか書き込まれません。
取得したデータすべてをcsvに書き込むにはどうしたら教えていただけたら幸いです。
よろしくお願いいたします。

# _*_ coding:utf-8 _*_
require 'anemone'
require 'nokogiri'
require 'open-uri'
require 'kconv'
require 'csv'

urls = ['http://www.amazon.co.jp/product-reviews/ISBNの番号/ref=cm_cr_pr_btm_link_1?ie=UTF8&showViewpoints=0&sortBy=recent&reviewerType=all_reviews&formatType=all_formats&filterByStar=all_stars&pageNumber=1']

opts = {
    :depth_limit => false,
    :obey_robots_txt => true,
    :delay => 3
}

Anemone.crawl(urls, opts) do |anemone|
    anemone.skip_links_like /next_+|prev+|unsticky/
    
    anemone.focus_crawl do |page|
        page.links.keep_if { |link|
            link.to_s.match(
                /product-reviews\/ISBNの番号\/ref=cm_cr_pr_btm_link_/)
        }
    end
    
    PATTERN = 
        %r[ref=cm_cr_pr_btm_link_]
    anemone.on_pages_like(PATTERN) do |page|
    
    doc = Nokogiri::HTML.parse(page.body.toutf8)
    
        
        
        retxt = []
        tit = []
        hyo = []
        retim = []
        renam = []
        san = []
        
        reviewtext = doc.xpath("//span[@class='a-size-base review-text']")
        title = doc.xpath("//a[@class='a-size-base a-link-normal review-title a-color-base a-text-bold']")
        hyoka = doc.xpath("//div[@class='a-section review']/div[2]/a[1]/i/span")
        reviewtime = doc.xpath("//div[@class='a-section review']/div[3]/span[4]")
        reviewname = doc.xpath("//*[@class='a-section review']/div[3]/span[1]/a")
        sankou = doc.xpath("//*[@class='a-section review']/div[1]/span")
        
            reviewtext.each do |node|
                retxt << node.text
            end
            title.each do |node|
                tit << node.text
            end
            hyoka.each do |node|
                hyo << node.text
            end
            reviewtime.each do |node|
                retim << node.text
            end
            reviewname.each do |node|
                renam << node.text
            end
            sankou.each do |node|
                san << node.text
            end
        
            puts sankou.text, reviewtext.text, title.text, hyoka.text, reviewtime.text, reviewname.text, sankou.text
        
            File.open('hibana2.csv', 'w') do |csv|
                retxt.length.times do |i|
                    csv << [retxt[i], tit[i], hyo[i], retim[i], renam[i], san[i]]
                end
            end
        
        
    end    
end

#sankou = doc.xpath("//div[@style='margin-left:0.5em;']/div[@style='margin-bottom:0.5em;']").text

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

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

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

    クリップを取り消します

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

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

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

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

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

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

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

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

    質問の評価を下げる

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

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

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

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

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

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

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

    詳細な説明はこちら

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

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

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

回答 2

checkベストアンサー

0

CSV書き込みのところがおかしいかな?

CSV.open("hibana2.csv", "wb") do |csv|
  retxt.length.times do |i| 
    csv << [retxt[i], tit[i], hyo[i], retim[i], renam[i], san[i]] 
  end 
end

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2015/07/31 18:08

    ご回答有難うございます。
    ご指摘のとおりに修正して試してみましたがこれまでと同じように一部しかcsvに書き込まれません。
    データ取得自体はできていると思います(コマンドプロンプト上に表示されているので)。

    キャンセル

  • 2015/07/31 18:12

    大体何件ぐらい取得して、何件ぐらいの書き込みで失敗していますか?

    キャンセル

  • 2015/07/31 18:20

    見落としてました。
    一括で書き込みするなら、
    結果を格納する配列(retxt,tit,hyo,retim,renam,san)の宣言部をAnemone.crawlブロックの前、CSV.openをAnemone.crawlブロックの後に出してみてください。
    毎行追加するなら、CSV.openブロックの位置は変えずに、
    CSV.open("hibano2.csv", 'a') do |csv|
    csv << [sankou.text, reviewtext.text, title.text, hyoka.text, reviewtime.text, reviewname.text, sankou.text]
    end
    で行けると思います。
    多分、ここだと思います。

    キャンセル

  • 2015/07/31 18:43

    取得件数は450件ほどだと思います。
    書き込みに成功したのが10件で、コマンドプロンプト上で最後に表示されていたので、最後にクローリングで取得したページに載っているレビューのデータ10件分が書き込まれていると思います。

    キャンセル

  • 2015/08/01 00:01

    ご指摘通りに変更したら上手くいきました!ありがとうございます!

    キャンセル

0

細かくは見てませんが、ページごとにループしているにもかかわらず、そのループ内でFile.open('hibana2.csv', 'w') しているので、ループごとにファイルを上書きして、最後のページの分しか残っていないということではないでしょうか。

openをループの外に出すのが簡単な変更ですね。


投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2015/08/01 00:02

    なるほど、確かにそうなのかもしれません。
    まだまだ初心者なので、なぜそうなるのかを教えていただけて非常にありがたいです!

    キャンセル

  • 2015/08/01 08:18

    >なぜそうなるのかを教えていただけて非常にありがたいです!
    回答に書いたとおりなのですが、「上書き」という概念が分からないのでしょうか?

    紙に文字が書いてあるとして、「上書き」というのは書いてあった文字を全部消しゴムで消してから書き直すと言うことです。なので、最後に書いた物しか残らない。
    消しゴムで消すのを、書く毎に行うので無く、プログラム最初で1回だけ行えば良かったのにと言うことです。

    消しゴムで消すのをやめる(=File.open('hibana2.csv', 'a')にする)というのでもいいのですが、プログラム全体を何度も実行すると、どんどん書かれたことが増える一方なので、プログラムの実行の最初で一度だけ消しゴムをつかうのが良いだろうと言うことです。

    キャンセル

関連した質問

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

  • Ruby

    7938questions

    Rubyはプログラミング言語のひとつで、オープンソース、オブジェクト指向のプログラミング開発に対応しています。