RubyによるWebスクレイピングでの404エラー対策
受付中
回答 3
投稿
- 評価
- クリップ 2
- VIEW 3,255
対象のURLは末尾の7桁の数字を変更して、変更した先のh2要素を抜くというものです。
初回のアクセス時にbasic認証があり、mechanizeで対策をしたのですが(以下コード)
現在問題点は2つございます。
①unexpected end of input errorが起きているが場所がわからない
②mechanizeの書き方が間違っていないか?
ご教示いただけると幸いです
require './Loader.rb'
require 'open-uri'
require 'openssl'
require 'nokogiri'
require 'mechanize'
test = Loader.new
test.loading
agent = WWW::Mechanize.new{|a| a.log=Logger.new('access.log')}
agent.verify_mode = OpenSSL::SSL::VERIFY_NONE
agent.user_agent = 'Windows IE11'
agent.add_auth("URLパス", 'ユーザー名', 'パスワード')
url = "対象URL"
$arry.each do $num
charset = nil
begin
html = open(agent.get(url)) do |f|
charset = f.charset
f.read
rescue Timeout::Error
puts "caught Timeout::Error!"
retry # タイムアウト用
rescue WWW::Mechanize::ResponseCodeError => e
case e.response_code
when "404"
puts "caught Net::HTTPNotFound!"
next # 404用
when "502"
puts "caught Net::HTTPBadGateway!"
retry # 502用
else
puts "caught Excepcion!" + e.response_code
retry
end
doc = Nokogiri::HTML.parse(html, nil, charset)
doc.xpath('//div[@id="main"]/h2').each do |node|
p node
end
end
-
気になる質問をクリップする
クリップした質問は、後からいつでもマイページで確認できます。
またクリップした質問に回答があった際、通知やメールを受け取ることができます。
クリップを取り消します
-
良い質問の評価を上げる
以下のような質問は評価を上げましょう
- 質問内容が明確
- 自分も答えを知りたい
- 質問者以外のユーザにも役立つ
評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。
質問の評価を上げたことを取り消します
-
評価を下げられる数の上限に達しました
評価を下げることができません
- 1日5回まで評価を下げられます
- 1日に1ユーザに対して2回まで評価を下げられます
質問の評価を下げる
teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。
- プログラミングに関係のない質問
- やってほしいことだけを記載した丸投げの質問
- 問題・課題が含まれていない質問
- 意図的に内容が抹消された質問
- 過去に投稿した質問と同じ内容の質問
- 広告と受け取られるような投稿
評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。
質問の評価を下げたことを取り消します
この機能は開放されていません
評価を下げる条件を満たしてません
質問の評価を下げる機能の利用条件
この機能を利用するためには、以下の事項を行う必要があります。
- 質問回答など一定の行動
-
メールアドレスの認証
メールアドレスの認証
-
質問評価に関するヘルプページの閲覧
質問評価に関するヘルプページの閲覧
+3
ruby -c file_name.rb
で構文チェックを走らせるとわかりやすいです
*
$arry.each
に処理を詰め込みすぎています 処理のグループ分け(名前付け)をして、関数に切り出しましょう
* グローバル変数の利用は避け、そういったシーンではクラスを定義してその中でインスタンス変数を利用するとよいかもしれません
* if と同様に、
do...end
もネストを深くしないよう関数に切り出すなどで浅く保つ
まずは見易いコードに整え、そのあとで構文エラーに対応しても遅くはないと思います
# 生の処理を関数に換える
例外が発生する処理も、
yield
を利用すると関数として切り出すことができるとおもいます
例:
def calc
yield
rescue ZeroDivisionError => e
puts e.message
end
puts calc { 1 + 1 } # => 2
puts calc { 0 / 0 } # => divided by 0
Mechanize の初期化:
def mechanize_agent
agent = WWW::Mechanize.new { |a| a.log = Logger.new('access.log') }
agent.verify_mode = OpenSSL::SSL::VERIFY_NONE
agent.user_agent = 'Windows IE11'
agent.add_auth('URLパス', 'ユーザー名', 'パスワード')
agent
end
このように関数として切り出していくと、構文エラーの発生しにくいコードにしていくことができるのではないでしょうか
何か参考になれば幸いです
# Links
* bbatsov/rubocop - GitHub
* Ruby - Rubocopを使ってコーディングルールへの準拠チェックを自動化 - Qiita
投稿
-
回答の評価を上げる
以下のような回答は評価を上げましょう
- 正しい回答
- わかりやすい回答
- ためになる回答
評価が高い回答ほどページの上位に表示されます。
-
回答の評価を下げる
下記のような回答は推奨されていません。
- 間違っている回答
- 質問の回答になっていない投稿
- スパムや攻撃的な表現を用いた投稿
評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。
0
インデントを正しくすれば、endの抜けに気づけると思います。二カ所ですね。
インデントを全くしないのでもなく、でたらめにするというのは、何故なんですかね?
2. $arry や $num は、Loader.rb で定義されているのだと思いますが、グローバル変数経由以外の方法がおそらくとれると思います。
3. $num が意味不明に置かれています。
4. リトライしても又同じエラーになりそうな気がしますけど。
5. each ループ内にこれくらいの機能の処理を書くのは良いと思いますが、エラー処理が混ざっているのが見にくいですね。aget.getに一皮かぶせたメソッドを作って、その中でエラー処理をするのがいいように思います。
6. require './Loader.rb' は、「実行時のカレントディレクトリにあるLoader.rb」を読み込みますが、意図と合っていますか?「このスクリプトと同じディレクトリにあるLoader.rb」の場合は、require_relative 'Loader.rb' です。
投稿
-
回答の評価を上げる
以下のような回答は評価を上げましょう
- 正しい回答
- わかりやすい回答
- ためになる回答
評価が高い回答ほどページの上位に表示されます。
-
回答の評価を下げる
下記のような回答は推奨されていません。
- 間違っている回答
- 質問の回答になっていない投稿
- スパムや攻撃的な表現を用いた投稿
評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。
0
他の方が指摘されているようにbegin内の
html = open(agent.get(url)) do |f|
に対してendが無いように見受けられます。
私も初心者で
やりたいことに合致するかわかりませんが、
下記のようにしてみてはいかがでしょうか?
begin
page = agent.get(url)
rescue Timeout::Error
puts "caught Timeout::Error!"
retry # タイムアウト用
rescue Mechanize::ResponseCodeError => e
case e.response_code
when "404"
puts "caught Net::HTTPNotFound!"
when "502"
puts "caught Net::HTTPBadGateway!"
retry # 502用
else
puts "caught Excepcion!" + e.response_code
retry
end
end
お役に立てれば幸いです。
投稿
-
回答の評価を上げる
以下のような回答は評価を上げましょう
- 正しい回答
- わかりやすい回答
- ためになる回答
評価が高い回答ほどページの上位に表示されます。
-
回答の評価を下げる
下記のような回答は推奨されていません。
- 間違っている回答
- 質問の回答になっていない投稿
- スパムや攻撃的な表現を用いた投稿
評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。
15分調べてもわからないことは、teratailで質問しよう!
- ただいまの回答率 88.37%
- 質問をまとめることで、思考を整理して素早く解決
- テンプレート機能で、簡単に質問をまとめられる
2015/11/09 13:19
的確なアドバイスありがとうございます。まずは頭の整理ふくめて、関数単位の切出しやってみます