Nano Hash - криптовалюты, майнинг, программирование

Nokogiri, open-uri и символы Unicode

Я использую Nokogiri и open-uri, чтобы получить содержимое тега title на веб-странице, но у меня проблемы с акцентированными символами. Каков наилучший способ справиться с этим? Вот что я делаю:

require 'open-uri'
require 'nokogiri'

doc = Nokogiri::HTML(open(link))
title = doc.at_css("title")

На данный момент заголовок выглядит так:

Тряпка\303\271

Вместо:

рагу

Как заставить nokogiri вернуть правильный символ (например, ù в данном случае)?

Вот пример URL:

http://www.epicurious.com/recipes/food/views/Tagliatelle-with-Duck-Ragu-242037


  • Тем, кто помогает, было бы полезно, если бы мы могли получить URL-адрес сайта, чтобы мы могли протестировать его. 03.04.2010
  • Как вы потом проверяете заголовок и какую версию Ruby вы используете? Rag\303\271 имеет Ragù кодировку UTF-8. 03.04.2010
  • Привет, Младен, я использую Ruby 1.8.6. Я просматриваю заголовок из интерактивной консоли Ruby. В конечном итоге он хранится в базе данных MySQL. В MySQL это выглядит так: ù 03.04.2010

Ответы:


1

Когда вы говорите «выглядит так», вы просматриваете это значение IRB? Он будет экранировать символы диапазона, отличные от ASCII, с экранированием в стиле C последовательностей байтов, которые представляют символы.

Если вы напечатаете их с помощью puts, вы получите их обратно, как и ожидали, предполагая, что ваша консоль оболочки использует ту же кодировку, что и рассматриваемая строка (по-видимому, в этом случае UTF-8, на основе двух байтов, возвращенных для этого символа) . Если вы сохраняете значения в текстовом файле, печать в дескриптор также должна привести к последовательностям UTF-8.

Если вам нужно выполнить перевод между UTF-8 и другими кодировками, особенности зависят от того, используете ли вы Ruby 1.9 или 1.8.6.

Для версии 1.9: http://blog.grayproductions.net/articles/ruby_19s_string для версии 1.8 вы, вероятно, надо посмотреть на Iconv.

Кроме того, если вам нужно взаимодействовать с COM-компонентами в Windows, вам нужно указать ruby ​​использовать правильную кодировку примерно следующим образом:

require 'win32ole'

WIN32OLE.codepage = WIN32OLE::CP_UTF8

Если вы взаимодействуете с mysql, вам необходимо установить параметры сортировки в таблице так, чтобы они поддерживали кодировку, с которой вы работаете. В общем, лучше всего установить сопоставление на UTF-8, даже если часть вашего контента возвращается в других кодировках; вам просто нужно преобразовать по мере необходимости.

В Nokogiri есть некоторые возможности для работы с разными кодировками (вероятно, через Iconv), но я немного отвык от этого, поэтому я оставлю объяснение этого кому-то другому.

03.04.2010
  • Привет, Джейсон! Большое спасибо за помощь. Получил, работает отлично. Я установил для своей кодировки базы данных MySQL значение UTF-8, а также для своего профиля терминала. 04.04.2010
  • @Moe Это может быть «решение» проблемы или ее маскировка. См. мой ответ о том, как четко убедиться, что Nokogiri получает правильный контент UTF-8. 16.01.2011

  • 2

    Вывод: при передаче UTF-8 в Nokogiri через open-uri используйте open(...).read и передайте полученную строку в Nokogiri.

    Анализ: если я извлекаю страницу с помощью curl, заголовки правильно отображают Content-Type: text/html; charset=UTF-8, а содержимое файла включает допустимую кодировку UTF-8, например. "Genealogía de Jesucristo". Но даже с волшебным комментарием к Ruby-файлу и установкой кодировки doc никуда не годится:

    # encoding: UTF-8
    require 'nokogiri'
    require 'open-uri'
    
    doc = Nokogiri::HTML(open('http://www.biblegateway.com/passage/?search=Mateo1-2&version=NVI'))
    doc.encoding = 'utf-8'
    h52 = doc.css('h5')[1]
    puts h52.text, h52.text.encoding
    #=> Genealogà a de Jesucristo
    #=> UTF-8
    

    Мы видим, что это не вина open-uri:

    html = open('http://www.biblegateway.com/passage/?search=Mateo1-2&version=NVI')
    gene = html.read[/Gene\S+/]
    puts gene, gene.encoding
    #=> Genealogía
    #=> UTF-8
    

    Кажется, это проблема Nokogiri при работе с open-uri. Это можно обойти, передав HTML в виде необработанной строки в Nokogiri:

    # encoding: UTF-8
    require 'nokogiri'
    require 'open-uri'
    
    html = open('http://www.biblegateway.com/passage/?search=Mateo1-2&version=NVI')
    doc = Nokogiri::HTML(html.read)
    doc.encoding = 'utf-8'
    h52 = doc.css('h5')[1].text
    puts h52, h52.encoding, h52 == "Genealogía de Jesucristo"
    #=> Genealogía de Jesucristo
    #=> UTF-8
    #=> true
    
    15.01.2011
  • Большое спасибо за этот ответ! 27.12.2011
  • Вау, я бы никогда не понял, что добавление .read исправит это. Спасибо! 04.11.2015

  • 3

    У меня была та же проблема, и подход Iconv не работал. Nokogiri::HTML является псевдонимом Nokogiri::HTML.parse(thing, url, encoding, options).

    Итак, вам просто нужно сделать:

    doc = Nokogiri::HTML(open(link).read, nil, 'utf-8')

    и он правильно преобразует кодировку страницы в utf-8. Вы увидите Ragù вместо Rag\303\271.

    24.01.2011

    4

    Попробуйте установить параметр кодирования Nokogiri, например:

    require 'open-uri'
    require 'nokogiri'
    doc = Nokogiri::HTML(open(link))
    doc.encoding = 'utf-8'
    title = doc.at_css("title")
    
    31.07.2010

    5

    Вам необходимо преобразовать ответ с очищаемого веб-сайта (здесь epicurious.com) в кодировку utf-8.

    в соответствии с html-содержимым с очищаемой страницы, на данный момент это «ISO-8859-1». Итак, вам нужно сделать что-то вроде этого:

    require 'iconv'
    doc = Nokogiri::HTML(Iconv.conv('utf-8//IGNORE', 'ISO-8859-1', open(link).read))
    

    Подробнее об этом читайте здесь: http://www.quarkruby.com/2009/9/22/rails-utf-8-and-html-screen-scraping

    04.04.2010
  • Из предоставленного образца видно, что его содержимое уже в кодировке UTF-8. 08.04.2010
  • нет, это не так. иначе он получил бы только ù. веб-страница не в кодировке utf-8 08.04.2010
  • \303\271 — это значения байтов UTF-8 с экранированием c, именно так они отображаются в IRB, когда вы смотрите на оцениваемую строку; это восьмеричная для C3 B9, которая является последовательностью UTF-8 для ù. Если бы это был iso-8859-1, он бы получил восьмеричное число для F9 или \371. 10.04.2010
  • но тогда почему это должно выглядеть как ù в mysql? Насколько я понимаю, его irb не может отображать utf-8, верно? 13.04.2010
  • Это была отдельная проблема, которую я объяснил в своем ответе. Сопоставление Mysql должно быть установлено для UTF-8 в таблице, в которой вы сохраняете данные. IRB может отображать текст UTF-8 на соответствующих терминалах, но он не будет отображать оцененные выражения как UTF-8. Он показывает оцененные выражения как экранированные последовательности ASCII + Octal. (пути могут вести себя по-разному. См. puts "\001" против "\001" в irb для примера, который не является специфичным для UTF-8.) 21.04.2010
  • Смотрите мой «ответ» в процессе: заголовки utf-8, данные utf-8, open-uri возвращает utf-8, но Nokogiri проваливает его. 15.01.2011

  • 6

    Замена Nokogiri::HTML(...) на Nokogiri::HTML5(...) устранила проблемы, которые возникали у меня при синтаксическом анализе определенных специальных символов, в частности длинных тире.

    (Символы с акцентом в вашей ссылке прошли нормально в обоих случаях, поэтому не знаю, поможет ли это вам в этом.)

    ПРИМЕР:

    url = 'https://www.youtube.com/watch?v=4r6gr7uytQA'
    
    doc = Nokogiri::HTML(open(url))
    doc.title
    => "Josh Waitzkin â\u0080\u0094 How to Cram 2 Months of Learning into 1 Day | The Tim Ferriss Show - YouTube"
    
    doc = Nokogiri::HTML5(open(url))
    doc.title
    => "Josh Waitzkin — How to Cram 2 Months of Learning into 1 Day | The Tim Ferriss Show - YouTube"
    
    15.12.2019
  • Это сработало! Я использую Nokogiri уже много лет и никогда не знал о Nokogiri::HTML5. Для тех, кто заинтересован, вам нужно будет добавить гем nokogumbo в свой проект. 23.04.2020
  • Почему nokogumbo? 23.04.2020
  • Это единственный способ использовать Nokogiri::HTML5 (github.com/rubys/nokogumbo), иначе вы получите сообщение об ошибке, что модуль Nokogiri HTML5 не найден. Module: Nokogiri::HTML5 is defined in: lib/nokogumbo/html5.rb ( rubydoc.info/gems/nokogumbo/Nokogiri/HTML5), что означает вам понадобится драгоценный камень nokogumbo. 23.04.2020

  • 7

    Просто чтобы добавить перекрестную ссылку, эта страница SO содержит некоторую связанную информацию:

    Как заставить Nokogiri прозрачно возвращать незакодированный HTML-код объекты нетронуты?

    04.04.2010

    8

    Совет. вы также можете использовать гем Scrapifier для очень простого получения метаданных, таких как заголовок страницы, из URI. Все данные закодированы в UTF-8.

    Проверьте это: https://github.com/tiagopog/scrapifier

    Надеюсь, это будет полезно для вас.

    09.04.2014
    Новые материалы

    Кластеризация: более глубокий взгляд
    Кластеризация — это метод обучения без учителя, в котором мы пытаемся найти группы в наборе данных на основе некоторых известных или неизвестных свойств, которые могут существовать. Независимо от..

    Как написать эффективное резюме
    Предложения по дизайну и макету, чтобы представить себя профессионально Вам не позвонили на собеседование после того, как вы несколько раз подали заявку на работу своей мечты? У вас может..

    Частный метод Python: улучшение инкапсуляции и безопасности
    Введение Python — универсальный и мощный язык программирования, известный своей простотой и удобством использования. Одной из ключевых особенностей, отличающих Python от других языков, является..

    Как я автоматизирую тестирование с помощью Jest
    Шутка для победы, когда дело касается автоматизации тестирования Одной очень важной частью разработки программного обеспечения является автоматизация тестирования, поскольку она создает..

    Работа с векторными символическими архитектурами, часть 4 (искусственный интеллект)
    Hyperseed: неконтролируемое обучение с векторными символическими архитектурами (arXiv) Автор: Евгений Осипов , Сачин Кахавала , Диланта Хапутантри , Тимал Кемпития , Дасвин Де Сильва ,..

    Понимание расстояния Вассерштейна: мощная метрика в машинном обучении
    В обширной области машинного обучения часто возникает необходимость сравнивать и измерять различия между распределениями вероятностей. Традиционные метрики расстояния, такие как евклидово..

    Обеспечение масштабируемости LLM: облачный анализ с помощью AWS Fargate и Copilot
    В динамичной области искусственного интеллекта все большее распространение получают модели больших языков (LLM). Они жизненно важны для различных приложений, таких как интеллектуальные..