2010-07-07 10 views
21

Per noiosi motivi con Hpricot, ho bisogno di scrivere una funzione che ha passato un URL e restituisce l'intero contenuto della pagina come una singola stringa.Recupera il contenuto dell'URL come stringa

Sono vicino. So che ho bisogno di usare OpenURI, e dovrebbe essere simile a questa:

require 'open-uri' 
open(url) { 
    # do something mysterious here to get page_string 
} 
puts page_string 

Qualcuno può suggerire che cosa devo aggiungere?

risposta

16

Il metodo open passa un IO rappresentazione della risorsa al blocco quando i rendimenti. Si può leggere da esso utilizzando il metodo di IO#read

open([mode [, perm]] [, options]) [{|io| ... }] 
open(path) { |io| data = io.read } 
+0

grazie e grazie per spiegare cosa sta succedendo dietro le quinte – AP257

+0

Come aggiorneresti il ​​percorso delle risorse relative in pull HTML? – saihgala

11
require 'open-uri' 
open(url) do |f| 
    page_string = f.read 
end 

Vedi anche la documentazione di IO class

50

Si può fare lo stesso senza OpenURI:

require 'net/http' 
require 'uri' 

def open(url) 
    Net::HTTP.get(URI.parse(url)) 
end 

page_content = open('http://www.google.com') 
puts page_content 
+11

Qual è lo svantaggio di utilizzare open-uri? – Watusimoto

+3

Sì, è super confusionario che questa risposta più complicata abbia molti più voti rispetto agli altri. Ho provato a cercare personalmente un motivo e ho trovato [questa domanda/risposta] (http://stackoverflow.com/a/16764302/199712) che sembra raccomandare OpenURI su Net :: HTTP nella maggior parte dei casi, il che rende le cose più confuse . GRAZIE, OBAMA –

+4

open-uri internamente patch 'Kernel.open'. Ecco un [articolo] (http://sakurity.com/blog/2015/02/28/openuri.html) che parla delle cose di cui dovresti essere a conoscenza quando usi open-uri. Ho anche incontrato i conflitti di denominazione dei metodi 'open' quando lo si utilizza insieme ad altre librerie come bunny gem (che implementa anche' open') – EricC

-2

require 'open-uri' 
open(url) {|f| #url must specify the protocol 
str = f.read() 
} 
+1

Come differisce dalla soluzione menzionata in precedenza da Teoulas? –

2

Per rendere il codice un po 'più chiaro, il metodo OpenURI open restituirà il valore restituito dal blocco, in modo da poter assegnare open s' valore restituito alla variabile. Ad esempio:

xml_text = open(url) { |io| io.read } 
+0

bello, ecco una fodera per ottieni le gamme pubbliche IP di amazon EC2: 'ruby -r json -ropen-uri -e 'JSON.parse (aperto (" https://ip-ranges.amazonaws.com/ip-ranges.json ") {| io | io .read}) ["prefissi"]. each {| p | puts # {p ["ip_prefix"] if p ["service"] == "EC2"}; "' – akostadinov

+0

errore di battitura fisso nell'un-liner: ' ruby -r json -r open-uri -e 'JSON.parse (aperto ("https://ip-ranges.amazonaws.com/ip-ranges.json ") {| io | io.read}) [" prefissi "]. each {| p | puts p [" ip_prefix "] if p [" service "] ==" EC2 "}; '' – Magnus

4

Sono stato anche molto confuso su cosa utilizzare per prestazioni migliori e risultati rapidi. Ho corso un punto di riferimento per entrambi per renderlo più chiaro:

require 'benchmark' 
require 'net/http' 
require "uri" 
require 'open-uri' 

url = "http://www.google.com" 
Benchmark.bm do |x| 
    x.report("net-http:") { content = Net::HTTP.get_response(URI.parse(url)).body if url } 
    x.report("open-uri:") { open(url){|f| content = f.read } if url } 
end 

Il suo risultato è:

   user  system  total  real 
net-http: 0.000000 0.000000 0.000000 ( 0.097779) 
open-uri: 0.030000 0.010000 0.040000 ( 0.864526) 

Mi piacerebbe dire che dipende da ciò che il vostro requisito è e come si desidera elaborare .

-1

provare la seguente invece:

require 'open-uri' 
content = URI(your_url).read 
Problemi correlati