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

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

ただいまの
回答率

90.50%

  • Ruby

    9446questions

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

  • Google

    826questions

    Googleは、アメリカ合衆国に位置する、インターネット関連のサービスや製品を提供している企業です。検索エンジンからアプリケーションの提供まで、多岐にわたるサービスを提供しています。

  • スクレイピング

    467questions

    スクレイピングとは、公開されているWebサイトからページ内の情報を抽出する技術です。

検索結果を10件取得したい。

解決済

回答 1

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 103

yuzujoe

score 32

わからないこと

現在Rubyのクローラー作成において検索結果を10件取得するのを当面の目標にしていましてその方法が知りたく質問させて頂きました
まずはコードを載せます

class Search

  def scraping(keyword)
    submit_keyword(keyword)
    # ここで30件取得させたい
    @agent.page.search('div.g').map do |node|
      title = node.search('a')
      next if title.empty?
      query = URI.decode_www_form(URI(title.attr("href")).query)
      url = query[0][1]
      snipped = node.search('div.s > span.st')

      next if snipped.empty? || snipped.children.empty?
      {
        url: url,
        title: expect_tag(title.children.to_html),
      }

    end.reject do |list|
      list.nil?
    end
  end

  private

  def submit_keyword(keyword)
    @agent = Mechanize.new
    @agent.user_agent_alias = USER_AGENT
    @agent.get('https://www.google.co.jp/')
    @agent.page.form_with(name: 'f') do |form|
      form.q = keyword
    end.submit
  end

  def expect_tag(string)
    string.gsub(/(<b>|<\/b>|<br>|<\/br>|\R)/, '')
  end



end

CSV.open('math.csv', 'w') do |rank|
  rank << ["Keyword","Rank","Title","URL"]
end

File.open('keyword.txt') do |file|
  file.each_line do |line|

    keyword = line
    result = GoogleSearch.new.scraping(keyword)
    result.each_with_index do |value, i|
      puts "----------------------------------------------------------------------------------------------------"
        puts "Keyword : #{keyword}"
        puts "Rank    : #{i+1}"
        puts "URL     : #{value[:url]}"
        puts "Title   : #{value[:title]}"
      puts "----------------------------------------------------------------------------------------------------"

      CSV.open('math.csv', 'a') do |rank|
        rank << ["#{keyword}","#{i+1}","#{value[:title]}","#{value[:url]}"]
      end
    end
  end
end

このコードで検索結果も取得まではできているのですが10件をちゃんと撮れないキーワードの時もありましておそらくURLで次のページにとばいいのでしょうがその方法がうまくわかっていないです。

参考試したもの

https://tanuhack.com/python/google-scraping/

この記事を見てコードを書いてみましたがうまくできず他に何か参考になるようなサイトや方法ご存知でしたらご教授いただけないでしょうか?

追記

https://teratail.com/questions/187572
こちらの質問投稿で30件取得ができるようにはなったのですが取得された結果がgoogleのブラウザでの正確な結果とは違ったものが出てきている為に別の方法で取得できないかと思案しております

具体的には検索のキーワードによって1ページ目で取得できる件数が違ったりするので次のURLに対してアクセスしてきっちり10件取得できるようにしたいと思っております。
例(Rubyの際は10件取得できているがルイヴィトンの際は6件しか取得できてないなど)

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

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

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

    クリップを取り消します

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

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

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

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

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

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

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

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

    質問の評価を下げる

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

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

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

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

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

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

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

    詳細な説明はこちら

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

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

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

質問への追記・修正、ベストアンサー選択の依頼

  • user1

    2019/05/16 06:32 編集

    前に解決したのでは?
    https://teratail.com/questions/187572
    「10件をちゃんと撮れないキーワード」について具体的な例があったほうが調査しやすいと思います。
    (私の環境ではブラウザで「青空文庫」と検索した場合、1ページに目に7件しか表示されていないので正しい挙動な気もします)

    キャンセル

  • yuzujoe

    2019/05/18 23:52

    ありがとうございます。

    追記内容に掲載させて頂きました。
    不足点などありましたらご指摘よろしくお願い致します

    キャンセル

回答 1

checkベストアンサー

0

  1. 表示件数分だけ表示する
    表示件数(今回の場合は10件)以上になるまでURLを取得して、表示件数分だけ表示するという方法で実現可能です。

  2. 「ブラウザでの正確な結果」を返却できるようにする
    ブラウザを自動操作して検索結果のhtmlをパースすることで「ブラウザでの正確な結果」を返せるようにできます。

require 'watir'
require 'nokogiri'
require 'cgi'

browser = Watir::Browser.new :chrome, switches: ['--headless --disable-gpu --incognito']

TGT_LIMIT = 10 # 表示する件数の制御をしている箇所
urls = []
pg_cnt = 0
url_base = 'https://www.google.com/search?q='
srch_word = CGI.escape('ルイヴィトン')

catch :while_brk do
  while urls.size < TGT_LIMIT do
    pg_url = url_base + srch_word
    unless pg_cnt.zero?
      pg_url += "&ei=123&start=#{pg_cnt * 10}"
    end
    pg_cnt += 1

    browser.goto(pg_url)
    html = browser.execute_script('return document.documentElement.innerHTML')
    doc = Nokogiri::HTML.parse(html)

    catch :loop_brk do
      loop do
        doc.xpath('//*[@id="topstuff"]/div/div/p[1]/em').each do |txt|
          throw :loop_brk
        end
        doc.xpath('//*[@id="rso"]/div').each do |tgt|
          throw :loop_brk
        end

        sleep(3)

        html = browser.execute_script('return document.documentElement.innerHTML')
        doc = Nokogiri::HTML.parse(html)  
      end
    end

    doc.xpath('//*[@id="topstuff"]/div/div/p[1]').each do |txt|
      throw :while_brk if txt.xpath('text()').text.include?('に一致する情報は見つかりませんでした。')
    end

    doc.xpath('//*[@id="rso"]/div').each do |div_tag|
      div_tag.xpath('div/div').each do |dd_tag|
        dd_tag.xpath('div/div/div[1]').each do |tgt|
          tgt_url = tgt.xpath('a/@href').text
          tgt_title = tgt.xpath('a/h3/text()').text
          next if tgt_title.strip == '' 
          urls << { title: tgt_title, url: tgt_url }
        end
      end
    end

    sleep(rand(3..5))
  end
end

browser.quit

if urls.size.zero?
  puts '検索結果は 0件 でした'
else
  urls.each_with_index do |url, i|
    break if i >= TGT_LIMIT
    puts "タイトル:#{url[:title]}"
    puts "URL:#{url[:url]}"
    puts
  end
end


  

投稿

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2019/05/23 10:25

    詳細な返答頂きましてありがとうございます。

    ブラウザについての知識が低いと自分でも感じたのでしっかり勉強して取り組みたいと思います。

    キャンセル

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

  • Ruby

    9446questions

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

  • Google

    826questions

    Googleは、アメリカ合衆国に位置する、インターネット関連のサービスや製品を提供している企業です。検索エンジンからアプリケーションの提供まで、多岐にわたるサービスを提供しています。

  • スクレイピング

    467questions

    スクレイピングとは、公開されているWebサイトからページ内の情報を抽出する技術です。