2010-07-07 19 views
21

Pour des raisons fastidieuses liées à Hpricot, j'ai besoin d'écrire une fonction qui est passée à une URL, et retourne tout le contenu de la page en une seule chaîne.Récupérer le contenu de l'URL sous forme de chaîne

Je suis proche. Je sais que je dois utiliser openURI, et il devrait ressembler à ceci:

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

Quelqu'un peut-il suggérer ce que je dois ajouter?

Répondre

16

La méthode open passe une représentation IO de la ressource à votre bloc quand il rendements. Vous pouvez lire en utilisant la méthode IO#read

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

merci et merci d'expliquer ce qui se passe dans les coulisses – AP257

+0

Comment voulez-vous mettre à jour le chemin vers les actifs relatifs en html tiré? – saihgala

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

Voir aussi la documentation de IO class

50

Vous pouvez faire la même chose sans 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

Quel est l'inconvénient d'utiliser open-uri? – Watusimoto

+3

Oui, c'est très déroutant que cette réponse plus compliquée ait plus de votes ascendants que les autres. J'ai essayé de chercher moi-même une raison et j'ai trouvé [cette question/réponse] (http://stackoverflow.com/a/16764302/199712) qui semble recommander OpenURI sur Net :: HTTP dans la plupart des cas, ce qui rend les choses plus confuses . MERCI, OBAMA –

+4

open-uri patches internes 'Kernel.open'. Voici un [article] (http://sakurity.com/blog/2015/02/28/openuri.html) qui parle des choses dont il faut être conscient lors de l'utilisation d'open-uri. J'ai également rencontré des conflits de nommage de méthode 'open' en l'utilisant avec d'autres bibliothèques telles que bunny gem (qui implémente également' open') – EricC

-2

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

Comment cela diffère-t-il de la solution mentionnée précédemment par Teoulas? –

2

Pour rendre le code un peu plus clair, la méthode openURI open retourne la valeur retournée par le bloc, de sorte que vous pouvez attribuer une valeur de retour de open à votre variable. Par exemple:

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

nice, voici un one liner à get amazon EC2 public IP gammes: 'ruby -r json -ropen-uri -e 'JSON.parse (ouvrir (" https://ip-ranges.amazonaws.com/ip-ranges.json ") {| io | io .read}) ["prefixes"]. chaque {| p | met # {p ["ip_prefix"] si p ["service"] == "EC2"}; '' – akostadinov

+0

a corrigé une faute de frappe dans le one-liner: ' ruby -r json -r open-uri -e 'JSON.parse (ouvrir ("https://ip-ranges.amazonaws.com/ip-ranges.json ") {| io | io.read}) [" préfixes "]. chaque {| p | met p [" ip_prefix "] si p [" service "] ==" EC2 "}; – Magnus

4

J'ai également été très confus ce qu'il faut utiliser pour de meilleures performances et des résultats rapides. J'ai couru une référence à la fois pour le rendre plus clair:

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 

Son résultat est:

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

Je voudrais dire que cela dépend de ce que vos besoins et comment vous voulez traiter .

-1

Effectuez les opérations suivantes au lieu:

require 'open-uri' 
content = URI(your_url).read 
Questions connexes