2010-07-07 7 views
21

Aus mühsamen Gründen mit Hpricot zu schreiben, muss ich eine Funktion schreiben, die eine URL übergeben wird, und den gesamten Inhalt der Seite als eine einzelne Zeichenfolge zurückgibt.Abrufen des Inhalts der URL als Zeichenfolge

Ich bin nah dran. Ich weiß, ich brauche openURI zu verwenden, und es sollte wie folgt aussehen:

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

Kann jemand empfehlen, was ich hinzufügen müssen?

Antwort

16

Die open Methode übergibt eine IO Darstellung der Ressource auf dem Block, wenn es Erträge. Sie können es lesen Sie die IO#read Methode

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

danke und danke für die Erklärung, was hinter den Kulissen passiert. – AP257

+0

Wie würdest du den Pfad zu relativen Werten in gezogenem HTML updaten? – saihgala

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

Siehe auch die Dokumentation von IO class

50

Sie können ohne openURI das Gleiche tun:

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

Was ist der Nachteil der Verwendung von Open-uri ist? – Watusimoto

+3

Ja, es ist sehr verwirrend, dass diese kompliziertere Antwort viel mehr Upvotes hat als die anderen. Ich habe versucht, selbst nach einem Grund zu suchen und fand [diese Frage/Antwort] (http://stackoverflow.com/a/16764302/199712), die OpenURI über Net :: HTTP in den meisten Fällen zu empfehlen scheint, was die Dinge nur noch verwirrender macht . DANKE, OBAMA –

+4

Open-UI intern Patches 'Kernel.open'. Hier ist ein [Artikel] (http://sakurity.com/blog/2015/02/28/openuri.html) über Dinge zu sprechen, die man beachten sollte, wenn man open-uri benutzt. Ich bin auch auf Methoden Namenskonflikte "offen" gestoßen, wenn es zusammen mit anderen Bibliotheken wie Hase gem (die auch "open" implementiert) – EricC

-2

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

Wie unterscheidet sich das von der zuvor von Teoulas erwähnten Lösung? –

2

Um Code ein wenig klarer, wird die openURI open Methode den Wert durch den Block zurück zurückkehren, so können Sie open ‚s Rückgabewert auf Ihre Variablen zuweisen. Zum Beispiel:

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

schön, hier ist ein Liner dazu Get amazon EC2 öffentliche IP-Bereiche: 'ruby -r json -ropen-uri -e 'JSON.parse (offen (" https://ip-ranges.amazonaws.com/ip-ranges.json ") {| io | io .read}) ["prefixes"]. je {| p | puts # {p ["ip_prefix"] wenn p ["service"] == "EC2"}; ' – akostadinov

+0

fixierter Tippfehler im Einzeiler: ' ruby -r json -r öffnen-uri -e 'JSON.parse (öffnen ("https://ip-ranges.amazonaws.com/ip-ranges.json ") {| io | io.read}) [" Präfixe "]. je {| p | setzt p [" ip_prefix "] wenn p [" service "] ==" EC2 "}; '" – Magnus

4

Ich war auch sehr verwirrt, was für bessere Leistung und schnelle Ergebnisse zu verwenden. Ich lief für beide eine Benchmark, um es klar:

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 

Das Ergebnis ist:

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

Ich mag würde sagen, dass es hängt davon ab, was Ihre Anforderung ist, und wie Sie bearbeiten möchten .

-1

die stattdessen folgenden Versuchen:

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