2009-07-30 8 views
7

Ho un'applicazione Sinatra (http://analyzethis.espace-technologies.com) che fa il seguenteCome convertire una risposta Net :: HTTP a una determinata codifica in Ruby 1.9.1?

  1. Recuperare una pagina HTML (via rete/http)
  2. Creare un documento Nokogiri dal response.body
  3. estrarre alcune informazioni e inviare torna nella risposta. La risposta dovrebbe essere codificata in UTF-8

Quindi sono arrivato al problema mentre cercavo di leggere i siti che utilizzano codifiche Windows-1256 come www.filfan.com o www.masrawy.com.

Il problema è il risultato della conversione della codifica non è corretta anche se non vengono generati errori.

La rete/http response.body.encoding dà ASCII-8BIT che non possono essere convertiti in UTF-8

Se faccio Nokogiri :: HTML (response.body) e utilizzare i selettori CSS per ottenere certi contenuto dalla pagina - ad esempio il contenuto del tag title - Ricevo una stringa che quando richiamo string.encoding restituisce WINDOWS-1256. Io uso string.encode ("utf-8") e invio la risposta usando quello, ma ancora una volta la risposta non è corretta.

Qualche suggerimento o idea di cosa c'è che non va nel mio approccio?

risposta

3

ho trovato il seguente codice di lavoro per me, ora

def document 
    if @document.nil? && response 
    @document = if document_encoding 
        Nokogiri::HTML(response.body.force_encoding(document_encoding).encode('utf-8'),nil, 'utf-8') 
       else 
        Nokogiri::HTML(response.body) 
       end 
    end 
    @document 
end 

def document_encoding 
    return @document_encoding if @document_encoding 
    response.type_params.each_pair do |k,v| 
    @document_encoding = v.upcase if k =~ /charset/i 
    end 
    unless @document_encoding 
    #document.css("meta[http-equiv=Content-Type]").each do |n| 
    # attr = n.get_attribute("content") 
    # @document_encoding = attr.slice(/charset=[a-z1-9\-_]+/i).split("=")[1].upcase if attr 
    #end 
    @document_encoding = response.body =~ /<meta[^>]*HTTP-EQUIV=["']Content-Type["'][^>]*content=["'](.*)["']/i && $1 =~ /charset=(.+)/i && $1.upcase 
    end 
    @document_encoding 
end 
+0

Funziona benissimo! –

20

Perché Net :: HTTP non gestisce correttamente la codifica. Vedere http://bugs.ruby-lang.org/issues/2567

È possibile analizzare response['content-type'] che contiene il set di caratteri invece di analizzare l'intero response.body.

Quindi utilizzare force_encoding() per impostare la codifica corretta.

response.body.force_encoding("UTF-8") se il sito viene servito in UTF-8.

+0

Sebbene questa soluzione funzioni, questo problema mi è successo solo per determinati siti. Forse quando Content-Type include 'application/json', allora codifica in UTF-8 ...? Secondo http://stackoverflow.com/questions/9254891/what-does-content-type-application-json-charset-utf-8-really-mean, application/json implica UTF-8. –

+1

Il prossimo passo logico sarebbe quello di chiamare .encode! ('UTF-8') sulla stringa risultante e quindi eseguire l'elaborazione effettiva –

+0

@DmitryVyal Hai salvato il mio compagno di giorno – JustMichael

Problemi correlati