2010-05-03 6 views
7

Ich möchte Daten von dieser Seite erhalten:Wie kann ich mithilfe von OpenUri den Inhalt einer Weiterleitungsseite abrufen?

http://www.canadapost.ca/cpotools/apps/track/personal/findByTrackNumber?trackingNumber=0656887000494793 

aber diese Seite vorwärts:

http://www.canadapost.ca/cpotools/apps/track/personal/findByTrackNumber?execution=eXs1 

Also, wenn ich open verwenden, von openURI, um zu versuchen, die Daten zu holen, es wirft ein RuntimeError Fehler sagen HTTP redirection loop:

Ich bin nicht wirklich sicher, wie man diese Daten erhalten, nachdem es umleitet und diesen Fehler wirft.

+0

Ist open-uri zwingend von würden Sie auch mit einer anderen Rubin-Technologie zufrieden sein? –

+0

Eine andere Rubin-Tech ist definitiv in Ordnung, wenn es notwendig ist. – Shpigford

+0

'open-uri' behandelt bereits Redirect. Es irrt nur, wenn ich auf Umleitung-Schleife stoße – lulalala

Antwort

22

Sie benötigen ein Werkzeug wie Mechanize. Aus seiner Beschreibung:

Die Mechanize-Bibliothek wird für verwendet, um die Interaktion mit Websites zu automatisieren. Mechanize automatisch speichert und sendet Cookies, folgt Weiterleitungen, kann folgen Links und Formulare absenden. Formular Felder können ausgefüllt und gesendet werden. Mechanize verfolgt auch die Seiten, die Sie als Geschichte besucht haben.

das ist genau das, was Sie brauchen. So

sudo gem install mechanize 

dann

require 'mechanize' 
agent = WWW::Mechanize.new 
page = agent.get "http://www.canadapost.ca/cpotools/apps/track/personal/findByTrackNumber trackingNumber=0656887000494793" 

page.content # Get the resulting page as a string 
page.body # Get the body content of the resulting page as a string 
page.search(".somecss") # Search for specific elements by XPath/CSS using nokogiri 

und Sie sind bereit 'n' Roll rocken.

1

Die Website scheint einige der Redirection-Logik mit Sitzungen zu tun. Wenn Sie die Sitzungs-Cookies, die sie bei der ersten Anfrage senden, nicht zurücksenden, gelangen Sie in eine Weiterleitungsschleife. IMHO ist es eine beschissene Implementierung von ihrer Seite.

Allerdings habe ich versucht, die Cookies an sie zurück zu geben, aber ich habe es nicht zur Arbeit gebracht, also kann ich mir nicht ganz sicher sein, dass das hier alles ist.

+0

Richtig, das ist, was ich fragen ... weil es eine Umleitung ist, wie bekomme ich die Daten von der Seite, auf die es umleitet? – Shpigford

+0

Ich habe meine Antwort umformuliert, um meinen Standpunkt klarer zu machen. Ich habe nicht nur gesagt, dass es eine Weiterleitung war, ich habe auch erklärt, warum du in einer Schleife gelandet bist, hoffentlich sollte das jetzt klar sein. – Theo

1

Während Mechanisieren ein wunderbares Werkzeug ist, ziehe ich es vor, mein eigenes Ding zu "kochen".

Wenn Sie ernsthaft mit dem Parsen beschäftigen, können Sie sich diesen Code ansehen. Es dient dazu, Tausende von Websites auf internationaler Ebene jeden Tag zu crawlen und so weit ich recherchiert und optimiert habe, gibt es keinen stabileren Ansatz dafür, der es auch erlaubt, später auf Ihre Bedürfnisse hochzuschneiden.

require "open-uri" 
require "zlib" 
require "nokogiri" 
require "sanitize" 
require "htmlentities" 
require "readability" 

def crawl(url_address) 
self.errors = Array.new 
begin 
    begin 
    url_address = URI.parse(url_address) 
    rescue URI::InvalidURIError 
    url_address = URI.decode(url_address) 
    url_address = URI.encode(url_address) 
    url_address = URI.parse(url_address) 
    end 
    url_address.normalize! 
    stream = "" 
    timeout(8) { stream = url_address.open(SHINSO_HEADERS) } 
    if stream.size > 0 
    url_crawled = URI.parse(stream.base_uri.to_s) 
    else 
    self.errors << "Server said status 200 OK but document file is zero bytes." 
    return 
    end 
rescue Exception => exception 
    self.errors << exception 
    return 
end 
# extract information before html parsing 
self.url_posted  = url_address.to_s 
self.url_parsed  = url_crawled.to_s 
self.url_host   = url_crawled.host 
self.status   = stream.status 
self.content_type  = stream.content_type 
self.content_encoding = stream.content_encoding 
self.charset   = stream.charset 
if stream.content_encoding.include?('gzip') 
    document = Zlib::GzipReader.new(stream).read 
elsif stream.content_encoding.include?('deflate') 
    document = Zlib::Deflate.new().deflate(stream).read 
#elsif stream.content_encoding.include?('x-gzip') or 
#elsif stream.content_encoding.include?('compress') 
else 
    document = stream.read 
end 
self.charset_guess = CharGuess.guess(document) 
if not self.charset_guess.blank? and (not self.charset_guess.downcase == 'utf-8' or not self.charset_guess.downcase == 'utf8') 
    document = Iconv.iconv("UTF-8", self.charset_guess, document).to_s 
end 
document = Nokogiri::HTML.parse(document,nil,"utf8") 
document.xpath('//script').remove 
document.xpath('//SCRIPT').remove 
for item in document.xpath('//*[translate(@src, "ABCDEFGHIJKLMNOPQRSTUVWXYZ", "abcdefghijklmnopqrstuvwxyz")]') 
    item.set_attribute('src',make_absolute_address(item['src'])) 
end 
document = document.to_s.gsub(/<!--(.|\s)*?-->/,'') 
self.content = Nokogiri::HTML.parse(document,nil,"utf8") 
end 
Verwandte Themen