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

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

新規登録して質問してみよう
ただいま回答率
85.48%
Ruby

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

Q&A

解決済

1回答

6844閲覧

Ruby openuri スクレイピング

daigakuse-

総合スコア67

Ruby

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

0グッド

0クリップ

投稿2017/06/07 23:37

Rubyで画像ダウンロードを行うコードを書いています。
chromedriverを使いbing検索を行い画像URLを所得し、open可能なURLを厳選するコードなのですが、厳選する部分でいつも落ちてしまいます。文法のミスかなとは思うのですが、試行錯誤してもうまくいかず。

ruby

1require 'selenium-webdriver' 2require 'uri' 3require 'open-uri' 4require 'openssl' 5require 'fileutils' 6 7client = Selenium::WebDriver::Remote::Http::Default.new 8client.timeout = 300 9 10def valid_url?(url) 11 open(url) 12 rescue SocketError, OpenURI::HTTPError,OpenSSL::SSL::SSLError,Timeout::Error,URI::InvalidURIError 13 false 14end 15 16 17 18 19Names = [ 20"name1", 21"name2", 22"name3",] 23 24 25 26 27Names.each do | names | 28 29 driver = Selenium::WebDriver.for :chrome, :http_client => client 30 driver.navigate.to "https://www.bing.com/?scope=images&FORM=Z9LH1" 31 element = driver.find_element(:name, 'q') 32 element.send_keys names 33 element = driver.find_element(:name, 'go') 34 element.submit 35 path = "./"+names 36 FileUtils.mkdir_p(path) unless FileTest.exist?(path) 37 38 39 element = driver.find_elements(:xpath,'//a[@class="iusc"]') 40 links = element.map{|a| a.attribute('href')} 41 links.uniq! #重複削除 42 43 el = [] 44 allurls = [] 45 46 links.each.with_index(1) do |url,i| 47 48 n = 2 49 begin 50 driver.navigate.to url 51 rescue Timeout::Error,ECONNREFUSED::Error 52 if n==0 then 53 next 54 else 55 n=n-1 56 retry 57 end 58 end 59 sleep 2 60 61 n = 2 62 begin 63 tab2.click 64 rescue Timeout::Error 65 if n==0 then 66 next 67 else 68 n=n-1 69 retry 70 end 71 end 72 sleep 2 73 el = driver.find_elements(:xpath, '//a[@class="view_image"]') 74 src = el.map{|a| a.attribute('href')} 75 src.uniq!#重複削除 76 allurls.push(src[0]) 77 //700枚いったら終わり 78 if i >= 700 then 79 break 80 end 81 82 end 83 84 valid_urls = allurls.select{|url| valid_url?(url) } 85 86 puts valid_urls.length 87 88 valid_urls.each.with_index(1) do |urls,i| 89 if File.extname(urls).empty? == false then 90 filename = File.basename(urls) 91 file_path = path + "/" + filename 92 open(file_path, 'wb') do |file| 93 open(urls) do |data| 94 file.write(data.read) 95 end 96 end 97 end 98 sleep 1 99 end 100 driver.quit 101end
in `__read_nonblock': Connection reset by peer (Errno::ECONNRESET) from <internal:prelude>:77:in `read_nonblock' from .rbenv/versions/2.4.0/lib/ruby/2.4.0/net/protocol.rb:172:in `rbuf_fill' from .rbenv/versions/2.4.0/lib/ruby/2.4.0/net/protocol.rb:154:in `readuntil' from .rbenv/versions/2.4.0/lib/ruby/2.4.0/net/protocol.rb:164:in `readline' from .rbenv/versions/2.4.0/lib/ruby/2.4.0/net/http/response.rb:40:in `read_status_line' from .rbenv/versions/2.4.0/lib/ruby/2.4.0/net/http/response.rb:29:in `read_new' from .rbenv/versions/2.4.0/lib/ruby/2.4.0/net/http.rb:1446:in `block in transport_request' from .rbenv/versions/2.4.0/lib/ruby/2.4.0/net/http.rb:1443:in `catch' from .rbenv/versions/2.4.0/lib/ruby/2.4.0/net/http.rb:1443:in `transport_request' from .rbenv/versions/2.4.0/lib/ruby/2.4.0/net/http.rb:1416:in `request' from .rbenv/versions/2.4.0/lib/ruby/2.4.0/open-uri.rb:329:in `block in open_http' from .rbenv/versions/2.4.0/lib/ruby/2.4.0/net/http.rb:877:in `start' from .rbenv/versions/2.4.0/lib/ruby/2.4.0/open-uri.rb:323:in `open_http' from .rbenv/versions/2.4.0/lib/ruby/2.4.0/open-uri.rb:741:in `buffer_open' from .rbenv/versions/2.4.0/lib/ruby/2.4.0/open-uri.rb:212:in `block in open_loop' from .rbenv/versions/2.4.0/lib/ruby/2.4.0/open-uri.rb:210:in `catch' from .rbenv/versions/2.4.0/lib/ruby/2.4.0/open-uri.rb:210:in `open_loop' from .rbenv/versions/2.4.0/lib/ruby/2.4.0/open-uri.rb:151:in `open_uri' from .rbenv/versions/2.4.0/lib/ruby/2.4.0/open-uri.rb:721:in `open' from .rbenv/versions/2.4.0/lib/ruby/2.4.0/open-uri.rb:35:in `open' from url.rb:29:in `valid_url?' from url.rb:118:in `block (2 levels) in <main>' from url.rb:118:in `select' from url.rb:118:in `block in <main>' from url.rb:34:in `each' from url.rb:34:in `<main>'

コードのご指摘があれば頂きたいです。

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

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

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

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

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

guest

回答1

0

ベストアンサー

まず、Errno::ECONNRESETは、エラーメッセージに「Connection reset by peer」とあるように、通信でのエラーで、文法の問題ではありません。

1つの原因としては、open(url)したものをどこでも閉じていないので、開きっぱなしの接続が溜まっておかしくなっていることが考えられます。開いたIOを受け取る必要はなさそうなので、ブロックで閉じてしまえば解決するかもしれません。

ruby

1def valid_url?(url) 2 open url do 3 return true 4 end 5 rescue SocketError, OpenURI::HTTPError,OpenSSL::SSL::SSLError,Timeout::Error,URI::InvalidURIError 6 false 7end

投稿2017/06/08 00:15

maisumakun

総合スコア145184

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

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

daigakuse-

2017/06/09 15:04

とても参考になる指摘をありがとうございます。 参考にいただいたコードを実施しましたが同じエラーが出てしまいます。 end の位置を変えたりしてみたのですが、うまくいかないです。 rescueにErrno::ECONNRESETをセットする方法はありでしょうか?
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問