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

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

新規登録して質問してみよう
ただいま回答率
85.48%
スクレイピング

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

Ruby

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

Q&A

解決済

1回答

289閲覧

Scrapingで次のページで自動で移動する方法

KOO_

総合スコア58

スクレイピング

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

Ruby

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

0グッド

0クリップ

投稿2019/08/19 06:38

編集2019/08/24 08:06

現在スクレイピングを行なっております。

実現したい内容として、
1該当indexから一つずつshowへ移動し、必要情報を取得
2終わったら次のshowを取得
3取りきったら、次のページへ自動的に移動し1、2を繰り返す
となります。

先日もご質問させて頂き丁寧に回答頂きましたが、スキル不足もありプログラムを構成することが出来なかったので再質問とさせて頂きました。

もし可能であれば、以下のプログラムをベースにeachやwhileを使って次ページへ進むプログラムを教えて頂けないでしょうか?

よろしくお願い致します。

require 'rubygems' require 'mechanize' a = Mechanize.new { |agent| agent.user_agent_alias = "#"} page = a.get("#") urls = a.page.css("...").css("a").map { |x| +x["href"]} #sleep 5 urls.each { |x| p x begin a.get(x); p a.page.css("#").css("a").text(); #タイトル p a.page.css("#")[1].text(); #住所 p a.page.css("#").text(); #自社URL p a.page.css("#")[2].text(); #人数 sleep 5; rescue => e p e end p "" }

example

1require 'mechanize' 2 3agent = Mechanize.new 4agent.user_agent = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64)' 5 + ' AppleWebKit/537.36 (KHTML, like Gecko) Chrome/76.0.3809.100 Safari/537.36' 6 7urls = [] 8 9page = agent.get('https://teratail.com/feed/new/1') 10 11loop do 12 page.css('#mainContainer > div.boxContentWrap.btnNew.j-feedContentsWrapper > ul > li:nth-child(1) > div.C-questionFeedItem__main.boxItemContent > h2 > a').each do |a| 13 urls << a['href'] 14 end 15 break if page.css('#mainContainer > div.j-feedPagination.u-mt40 > div > p > a > span').empty? 16 sleep(rand(3..5)) 17 page = page.link_with(text: '次のページ').click 18end 19 20urls.each do |url| 21 page = agent.get(url) 22 puts page.css('#l-headContents > div > div.p-questionHead__main > h1').text 23 sleep(rand(3..5)) 24end 25

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

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

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

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

退会済みユーザー

退会済みユーザー

2019/08/19 11:54

2点質問があります。 1. 質問に記述されているコードは「このままの状態」で質問者さんの環境で動作しますか? 2. クロール対象のサイトは動的にページが生成されるタイプのものではないですか? ※ 動的に生成される場合、Mechanizeでは実現不能です。 可能であれば、対象サイトのHTMLを教えていただけるとコードが記述しやすいと思います。
KOO_

2019/08/19 13:35 編集

user1さん。引き続きこちらでも対応頂きありがとう御座います。折角前回も対応頂いたのに知識不足で改めてスレッドを立てることになり申し訳ありませんでした。 上記内容について回答させて頂きます。 1. はい。動作します。 2. スクレイピングする毎に違った情報が取得されるので動的だと思われます。  動的でも現在習得できているのですが、Mechanizeでは難しいとはどういうことなのでしょうか? また対象サイトのHTMLもお伝えしたいところなのですが、こちらに記載しても良いのもなのでしょうか?
退会済みユーザー

退会済みユーザー

2019/08/19 16:09 編集

スレッドを立てることは別に構いませんよ。 2について、例えばChromeで「Ctrl + U」と「F12(Elements)」でそれぞれHTMLを 確認できますが、両者で表示されるHTMLが異なっているサイトがあります。 このようなサイトかつ「F12(Elements)」で表示されるHTMLにのみ目的の要素が存在する 場合、Mechanizeでは取得が難しいです。 私には事情が分からないので対象のHTMLの公開については自分で判断してください。
guest

回答1

0

ベストアンサー

記事一覧をすべて取得して各ページのタイトルを表示するクローラー。

Ruby

1require 'mechanize' 2 3agent = Mechanize.new 4agent.user_agent = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64)' 5 + ' AppleWebKit/537.36 (KHTML, like Gecko) Chrome/76.0.3809.100 Safari/537.36' 6 7urls = [] 8 9page = agent.get('#') 10 11loop do 12 page.css('.article-title > a').each do |a| 13 urls << a['href'] 14 end 15 break if page.css('.paging-next').empty? 16 sleep(rand(3..5)) 17 page = page.link_with(text: '次のページ').click 18end 19 20urls.each do |url| 21 page = agent.get(url) 22 puts page.css('.article-title > a').text 23 sleep(rand(3..5)) 24end 25

追記

Ruby

1require 'mechanize' 2require 'csv' 3 4agent = Mechanize.new 5agent.user_agent = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64)' 6 + ' AppleWebKit/537.36 (KHTML, like Gecko) Chrome/76.0.3809.100 Safari/537.36' 7 8urls = [] 9 10begin 11 page = agent.get('https://teratail.com/') 12 13 1.step do |i| 14 page.css('.C-questionFeedItemTitle > a').each do |a| 15 urls << 'https://teratail.com' + a['href'] 16 end 17 sleep(rand(3..5)) 18 page = agent.get("https://teratail.com/feed/active/#{i + 1}") 19 end 20rescue Mechanize::ResponseCodeError 21 # Do Nothing 22end 23 24if urls.any? 25 lines = urls.map do |url| 26 sleep(rand(3..5)) 27 page = agent.get(url) 28 [page.css('.p-questionHead__ttl').text.encode('cp932')] 29 end 30 CSV.open("file.csv", "wb") do |csv| 31 lines.each { |line| csv << line } 32 end 33end 34

参考
class CSV
CSV を文字コード変換しつつロード

投稿2019/08/19 16:11

編集2019/08/24 10:35
退会済みユーザー

退会済みユーザー

総合スコア0

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

KOO_

2019/08/21 15:51

本当にご丁寧にありがとう御座います。何度かトライしてみたのですが、上記で行う場合、loopがあるとruby ファイル名.rbをターミナルで打っても動かないみたいなのですが、どのような原因が考えられますでしょうか。。。?
退会済みユーザー

退会済みユーザー

2019/08/21 22:26 編集

「動かない」が「何も結果が表示されない」ということであれば、恐らくCSSセレクタが原因でしょう。 対象サイトのHTMLが不明なため、適宜そちらで修正していただく必要があります。 加えて、 恐らく agent.get('#') のまま実行すると「ArgumentError」が発生します。
KOO_

2019/08/24 08:05

お世話になっております。せっかく教えて頂いているのでなんとか動かせるように持っていきたいので、当サイトhttps://teratail.com/のリストをスクレイピングする方法でご教示頂けないでしょうか?自分でやってみた限りでは、 page = page.link_with(text: '次のページ').click がundefined method `click' for nil:NilClass (NoMethodError) となります。 もし色々聞いてよければ、CSVファイルに抽出するところまでプログラムを回答頂けると非常に幸いです。 よろしくお願い致します。
退会済みユーザー

退会済みユーザー

2019/08/24 10:34

追記しました。MechanizeでJSが扱えないので「次のページ」を開く方法を変更しています。
KOO_

2019/08/25 15:31

ご丁寧にありがとう御座います。 私の方では同じプログラムで全く動作が進まないみたいです。。。 エラーも出ないようで中断するまでずっと黒画面が続きますがuser1様の方では動作もしているのでしょうか?
KOO_

2019/08/25 15:44

どうやら1.STEP のeachが回らないみたいで止まるよう。自分で解決出来ましたらご報告します!
退会済みユーザー

退会済みユーザー

2019/08/25 22:10 編集

特に指定がなかったので全ページのURLを先に取得してから動作します。 「1.STEP のeach」は回りますが、全ページのURLが取得されるまで各ページの タイトルの出力は行われません。動作確認の際は適当なところでbreakしてください。
KOO_

2019/08/31 08:35

すみません。出張でお返事出来ておりませんでした。今からもう一度トライしてみます。 取り急ぎお返事遅くなり、失礼しました。
KOO_

2019/09/01 06:13

breakしても何故か回らないみたいです。。。 一旦こちらもベストアンサーをつけさせていただきます。 ありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問