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

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

ただいまの
回答率

90.33%

  • Ruby

    8227questions

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

Rubyで作るクローラーについて

解決済

回答 2

投稿

  • 評価
  • クリップ 2
  • VIEW 448

abcdtaichi

score 7

前提・実現したいこと

はじめまして。
Rubyで「キーワードを検索したら、Googleの検索結果上位10サイトの記事タイトルと見出しをテキストで出力できる」というツールを作っています。

本やネットを参考に作っているのですが、色々と困っています汗
今質問したいのは

・実行をすると文字化けするものとそうでないものがある
・上位10サイト以外の画像・動画・ショッピング・地図といった部分を出力してしまう

他にも質問したいことは山ほどありますが、今はこの2つを解決したいです。
下記がコードになります。

該当のソースコード

require 'anemone'
require 'URI'

#キーワード入力からグーグルの検索URLまで
puts "キーワードを入力してください"
keyword = gets.chomp
word = URI.encode("https://www.google.co.jp/search?q=#{keyword}")

#巡回対象サイトのURLを指定・1階層下にいって探索
Anemone.crawl(word, :delay => 3,:depth_limit => 2) do |anemone|

#すべてのページに対しての処理
  anemone.on_every_page do |page|
    page.doc.xpath("a","//h2","//h3","//h4","//h5","//h6").each do |title|

      puts "----------------"
      puts title.text
    end
  end
end

お願い

プログラミングを独学で始めて5日目なので、かなり未熟です。
わからない部分は調べますが、できるだけわかりやすくご回答していただけると助かります。
それではよろしくお願いいたします。

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

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

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

    クリップを取り消します

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

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

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

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

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

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

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

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

    質問の評価を下げる

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

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

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

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

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

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

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

    詳細な説明はこちら

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

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

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

回答 2

checkベストアンサー

0

原因は、anemoneというgemがUTF-8という文字コード以外を全く考慮していないからです。
anemoneが内部で使用しているNokogiriはUTF以外からのエンコーディングにも対応しているので以下のように書き換えてあげてみてください。

anemone.on_every_page do |page|
  encoded_page = Nokogiri::HTML.parse(page.body.encode("utf-8","shift_jis"))
  encoded_page.xpath("a","//h2","//h3","//h4","//h5","//h6").each do |title|
     puts "----------------"
      puts title.text
  end
  ...
end

ちなみに、Google検索結果へのクローリングですが、基本的にGoogleからは非推奨とされています。
なので何回も同じWifiなどから行っているとクローリングできないようになりますのでご注意ください。

担当媒体の検索順位を自動的に取得できるツールなどは、SEOの会社などが自作していたり、購入できたりするのですが、あれもどのIPから検索しているのかを、偽装するようにして実現できているという感じです。

仮に質問者様がどうしても検索順位の10位を取得する機能を作りたい場合は、以下のような感じになるかと思います!

  1. プロキシサーバ(踏み台にするサーバ)を介して上記のrubyを実行
  2. 仮にGoogleから弾かれたら他のIPを設定する(このIPはネットでプロキシサーバ フリーなどで調べれば出てくるのでそのサイトを再度スクレイピングしてIPを見つけるみたいな感じです)
  3. 再度実行. 1に戻る

ちなみにanemoneがプロキシサーバのIPをセットできるかはわかりません。
rubyで同じようなことが出来るMechanizeというgemは可能でした。

頑張ってください!

投稿

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2017/09/13 19:08

    Masakakazu Fukami様

    ご回答ありがとうございます。
    書き換えをしたら、文字化けせずに取得できました。
    ただ上位10サイトの記事タイトルを出力してからがエラーになってしまいます。

    --------------------------------------------------

    キーワードを入力してください
    マリオ
    ----------------
    Search Options
    ----------------
    マリオ のニュース検索結果
    ----------------
    マリオポータル | Nintendo
    ----------------
    New スーパーマリオブラザーズ 2 - 任天堂
    ----------------
    マリオ (ゲームキャラクター) - Wikipedia
    ----------------
    マリオ&ルイージRPG1 DX トレーラー [E3 2017] - YouTube
    ----------------
    スーパーマリオ オデッセイ 2nd トレーラー [E3 2017] - YouTube
    ----------------
    開発者が紹介する スーパーマリオ オデッセイ [E3 2017] - YouTube
    ----------------
    スーパーマリオ ラン | 任天堂
    ----------------
    スーパーマリオ オデッセイ (@mario_odysseyJP) | Twitter
    ----------------
    マリオ の画像検索結果
    test2.rb:14:in `encode': "\x80" on Shift_JIS (Encoding::InvalidByteSequenceError)
    from test2.rb:14:in `block (2 levels) in <main>'
    from C:/Ruby24-x64/lib/ruby/gems/2.4.0/gems/anemone-0.7.2/lib/anemone/core.rb:229:in `block in do_page_blocks'
    from C:/Ruby24-x64/lib/ruby/gems/2.4.0/gems/anemone-0.7.2/lib/anemone/core.rb:228:in `each'
    from C:/Ruby24-x64/lib/ruby/gems/2.4.0/gems/anemone-0.7.2/lib/anemone/core.rb:228:in `do_page_blocks'
    from C:/Ruby24-x64/lib/ruby/gems/2.4.0/gems/anemone-0.7.2/lib/anemone/core.rb:167:in `block in run'
    from C:/Ruby24-x64/lib/ruby/gems/2.4.0/gems/anemone-0.7.2/lib/anemone/core.rb:163:in `loop'
    from C:/Ruby24-x64/lib/ruby/gems/2.4.0/gems/anemone-0.7.2/lib/anemone/core.rb:163:in `run'
    from C:/Ruby24-x64/lib/ruby/gems/2.4.0/gems/anemone-0.7.2/lib/anemone/core.rb:92:in `block in crawl'
    from C:/Ruby24-x64/lib/ruby/gems/2.4.0/gems/anemone-0.7.2/lib/anemone/core.rb:83:in `initialize'
    from C:/Ruby24-x64/lib/ruby/gems/2.4.0/gems/anemone-0.7.2/lib/anemone/core.rb:90:in `new'
    from C:/Ruby24-x64/lib/ruby/gems/2.4.0/gems/anemone-0.7.2/lib/anemone/core.rb:90:in `crawl'
    from C:/Ruby24-x64/lib/ruby/gems/2.4.0/gems/anemone-0.7.2/lib/anemone/core.rb:18:in `crawl'
    from test2.rb:10:in `<main>'

    ----------------------------------------------------

    「Encoding::InvalidByteSequenceError」について調べてみると、色々な種類があるようでどういうエラーかすらよくわかりません。
    このエラーはどう修正すればよろしいでしょうか?

    プロキシサーバーの件は承知いたしました。
    Googleは非推奨なんですね・・・汗
    サーバーを通してやってみます!

    詳しく説明していただき、ありがとうございます。!

    キャンセル

  • 2017/09/13 19:19

    もしかしたら
    require 'kconv'
    ~省略~
    Nokogiri::HTML.parse(page.body.toutf8)
    とかでいけるかもしれないです。

    キャンセル

0

require 'capybara/poltergeist'
require 'nokogiri'

Capybara.register_driver :poltergeist do |app|
  Capybara::Poltergeist::Driver.new(app, {:js_errors => false, :timeout => 5000 })
end

session = Capybara::Session.new(:poltergeist)

session.driver.headers = {
    'User-Agent' => "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/49.0.2564.97 Safari/537.36"
}

url = "https://www.google.co.jp/search?q=#{URI.escape(ARGV[0])}"
session.visit url

doc = Nokogiri::HTML.parse(session.html)

doc.xpath('//h3[@class="r"]/a[contains(@onmousedown, "return")]').each do |node|
  puts node.text
end

=begin
  「ruby test.rb あいう」で実行
   結果
   あいうべ体操で口呼吸を鼻呼吸に改善 | 福岡のみらいクリニック
   福岡のみらいクリニック | あいうべ体操とゆびのば体操で病気にならない体 ...
   口呼吸を改善する「あいうべ体操」 口腔ケアチャンネル 165 - YouTube
   あいうべ体操のブログ|インフルエンザ、口臭予防、歯並び改善、小顔 ...
   資格でできること - 資格コースのご案内|あいうべ協会
   口呼吸:「あいうべ体操」で舌筋を鍛えて舌と顔のたるみをとろう!:顔の ...
   1週間で実感!たった5秒で免疫力を上げるお口の体操「あいうべ体操」の ...
   インフルエンザ激減!【あいうべ体操】のスゴイ効果! - NAVER まとめ
   あいうべ体操 ~ 口呼吸をやめて健康になろう! ~|山口県下関市の ...
  あいうべ体操のやり方
=end

参考
Rubyでスクレイピング

投稿

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2017/09/13 19:30

    ご回答ありがとうございます。
    ソースコードとリンク先のサイトは参考にさせていただきます。

    またアドバイス通りに修正したら、上手くいきました!
    本当にありがとうございます!

    キャンセル

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

  • Ruby

    8227questions

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