Кракозябры при парсинге черег GET запрос

  • Автор темы Автор темы kasper
  • Дата начала Дата начала

kasper

Client
Регистрация
01.04.2012
Сообщения
139
Реакции
15
Баллы
18
Сталкивался уже на двух разных ресурсах при парсинге через get запрос. При получении DOM через браузер все нормально.
Пример:
Оперативники узнали, что в одном из ресторанов на северо-западе столицы готовится встреча представителей криминальных структур. Задержаны около 50 че��овек, их проверяют на причастность к преступлениям
Почему только часть текста, точнее 1 или 2 буквы? Можно как-то обойти проблему?
 
Кодировка запроса соответствует кодировке страницы?
 
Да. Везде utf-8.
Заметил еще, что как то рандомно появляется. Вот пример страницы: http://news.yandex.ru/yandsearch?cl4url=www.vestifinance.ru/articles/38218&lr=213&rpt=story
В процессе тестов эта хрень может появиться в разных местах текста, а может и не появиться вообще

П.С. Добавлю. пробовал в настройках экшена ставить и "только содержимое" и "заголовки и содержимое".

Дело не только в конкретном сайте, такое наблюдается на совершенно разных ресурсах
 
Да, тоже замечал что иногда проскакивают такие символы �� в отправляемом зенкой контенте.
 
Пришлите другой пример страницы, спрошу.
Н этом примере не вижу кракозябр в результате
http://news.yandex.ru/yandsearch?cl4url=www.vestifinance.ru/articles/38218&lr=213&rpt=story
Вот прямо сейчас по той же ссылке выловил:
тогда как индекс ММВБ вырос на 0,62%. …Внешний фон сегод??я нейтральный
Правда раза с третьего.
Попробуйте несколько раз повторить парсинг.

И как писал выше, при разных попытках символы могут появляться в разных местах текста, либо не появиться вообще.
 
7make, может вам шаблон с примером скинуть?
 
пожалуй апну тему. возможно ли сделать опцию автоопределения кодировки в get и post запросах?
 
Скиньте мне шаблон, хочу тоже научится как парсить текст с помощью get запросов, я так полагаю, что это быстрее, чем просто переходить по браузеру и парсить.
 
у меня маленько другая проблема.
я делаю запросы к многим сайтам. теоретически после 1го я могу определить кодировку, из meta charset, тогда нужно название кодировки вписать в настройках экшена. а там переменные не поддерживаются
конечно, как обычно можно запилить собственный экшен, но.... дальше я не знаю какие привести аргументы))
 
сниппетом кодировку менять полученной строки, автоопределение кодировки довольно не благодарное занятие на самом деле
 
не, не кодировку. второй запрос делать с правильной кодировкой
 
пожалуй апну тему. возможно ли сделать опцию автоопределения кодировки в get и post запросах?

Парсите заголовки сначала, оттуда кодировку, потом забираете содержимое страницы, подставляя какую кодировку юзать.
 
не всегда сайт возвращает в заголовке Content-Type: text/html; charset=

но но можно ориентироваться на тэг
<meta http-equiv="Content-Type" content="text/html; charset=windows-1251" />

можно делать зщапрос в УТФ-8, потом проверять содержимое этого тэга и\или в заголовке. и при необходимости делать второй запрос с другой кодировкой. вот такой костыль. да.
 
  • Оценить
Реакции: DrunkDeath и DenisK
не всегда сайт возвращает в заголовке Content-Type: text/html; charset=

Поддерживаю. Далеко не всегда.

Получается нужно делать два одинаковых подключения к одному URL (что совсем не круто). Ужасный костыль, неужели других вариантов нет?

Через код c# не получится изменить кодировку?

ps: на PHP я определял кодировку через биграммы с последующей сменой кодировки: http://habrahabr.ru/post/127658/
 
Даже если вы будете писать свой алгоритм определения кодировки, без запроса к странице вы как из нее данные получите? Никак.
 
а нельзя ли просто скачать бодик а в снипете уже рабираться в какой кодировке пришло тело. Делайте запрос в утф-8 (а лучше в ascii) a потом делаете перекодировку еще раз в утф-8. Все, вопрос решен.
 
Даже если вы будете писать свой алгоритм определения кодировки, без запроса к странице вы как из нее данные получите? Никак.

Естественно один запрос должен быть, думаю вы меня не так поняли. Предложенный выше "костыль" (для страниц с кодировкой отличной от UTF-8) требует отправки двух GET запросов:
1) узнает кодировку страницы по заголовкам/meta данным.
и если полученная кодировка не UTF-8, то:
2) делает повторный GET запрос с указанием в настройках полученной кодировки.

А как должно быть по хорошему: один GET запрос -> определяем кодировку по заголовкам/meta данным (или по какому либо алгоритму) -> конвертируем в UTF-8 для дальнейшей работы.

Делайте запрос в утф-8 (а лучше в ascii) a потом делаете перекодировку еще раз в утф-8.

Было бы здорово увидеть реализацию перекодирования на c# из известной кодировки (windows-1251, koi8-r, iso8859-5, raw) в UTF-8.
У самого накидать не получилось, с c# особо не дружу.
 
Делаю GET запрос ( с заданной в опциях кодировкой utf-8 ) к странице в кодировке Windows-1251. Предсказуемо получаю контент с � вместо кириллицы.

Выполняю следующий C# код, который по идее должен переводить содержимое из UTF-8 в Windows-1251.

Код:
Развернуть Свернуть Копировать
string content = project.Variables["content"].Value;
Encoding utf8 = Encoding.GetEncoding("UTF-8");
Encoding win1251 = Encoding.GetEncoding("Windows-1251");
byte[] utf8Bytes = win1251.GetBytes(content);
byte[] win1251Bytes = Encoding.Convert(utf8, win1251, utf8Bytes);
return win1251.GetString(win1251Bytes);

Но в итоге получаю ? вместо кириллицы. Выручайте светлые головы.

ps: сразу задавать в опциях GET запроса правильную кодировку не получится, т.к. целевые страницы могут быть в разной кодировке.
 
я тоже по всякому проверял - та же фигня.
Единственный выход использовать сторонние либы.
 
Решил проблему, отмучился, расписываю решение:

1) Делаем GET запрос к странице с выставленной кодировкой Windows-1251, получаем заголовки и содержимое.
2) Парсим регулярками кодировки из заголовков и из мета:
Код:
Развернуть Свернуть Копировать
(?i)(?<=\r\nContent-Type.*charset=)[\d\w-]*
(?i)(?<=meta.*charset=)[\d\w-]*
3) Приводим полученные кодировки к нижнему регистру.
4) Сравниваем сначала (приоритет заголовкам) кодировку из заголовка (если есть) с windows-1251 (и с её синонимом cp1251), если отличается - выполняем C# код представленный ниже -> PROFIT!
5) Если же кодировки из заголовка нет, то сравниваем кодировку из meta с windows-1251 (и с её синонимом cp1251), если отличается - выполняем C# код представленный ниже -> PROFIT!

Код:
Развернуть Свернуть Копировать
string content = project.Variables["content"].Value;
string charset = project.Variables["charset"].Value;
Encoding charset_en = Encoding.GetEncoding(charset);
Encoding win1251 = Encoding.GetEncoding("Windows-1251");
byte[] charsetBytes = win1251.GetBytes(content);
byte[] win1251Bytes = Encoding.Convert(charset_en, win1251, charsetBytes);
return win1251.GetString(win1251Bytes);

content - полученное содержимое
charset - кодировка в которой содержимое

PS: Если ни в заголовке, ни в meta кодировка не прописана - то остаётся только надеяться, что данные на странице были в Windows-1251. Тут уж поможет только определение кодировки другими алгоритмами, например Mozilla Universal Charset Detector (думаю было бы круто прикрутить к зеннке, в качестве автоопределятора/перегона кодировки).

PS2: интересно то, что если запрос изначально делать в UTF-8 то потом перевести полученные данные в другую кодировку не получается (кракозябры остаются).
 
Делаем GET запрос к странице с выставленной кодировкой Windows-1251, получаем заголовки и содержимое.
если контент уже раскодирован в Windows-1251, зачем повторно его перекодировать в ту же кодировку?
удачным решением будет если вы скачаете бодик без аксепт хедера (например курлом), распакуете его если нужно, переведете в утф-8 копию, найдете кодировку и ей же раскодируете оригинал.
 
если контент уже раскодирован в Windows-1251, зачем повторно его перекодировать в ту же кодировку?

Сравниваем кодировку с windows-1251 если отличается - выполняем C# код для смены кодировки в Windows-1251.

Читаем внимательней ;) Перекодирование осуществляется только для кодировок НЕ в Windows-1251.
 
так а если вы изначально не знаете кодировку, то как что делать?
или кодировка меняется периодически с утф на вин-1251 - что тогда?
Сравниваем кодировку с windows-1251 если отличается - выполняем C# код для смены кодировки в Windows-1251.
сравнили - отличается, оказывается это не вин-1251, а допустим кои какой нибудь кои - прекодирует?
У меня есть подозрение что, если зенка пахабит данные перекодированием в теле ответа то никакое пере-перекодирование не поможет.
Самое лучший способ - качать станицу в байтах, а там уже делай что хочешь.
 
так а если вы изначально не знаете кодировку, то как что делать?
или кодировка меняется периодически с утф на вин-1251 - что тогда?

Способ как раз и рассчитан на работу со страницами в "неизвестной" кодировке.
В любом случае обращаемся с выставленной в настройках GET запроса кодировкой Windows-1251 (к страницам в любых кодировках), получив заголовки и содержимое - дергаем регулярками кодировку контента (из заголовков и meta).

сравнили - отличается, оказывается это не вин-1251, а допустим кои какой нибудь кои - прекодирует?

Да, с# код я выложил. Попробуй, у меня всё получилось.
 
  • Оценить
Реакции: orka13
действительно, круто!
 
  • Оценить
Реакции: orka13

Кто просматривает тему: (Всего: 0, Пользователи: 0, Гости: 0)