Что нового

GET запрос на яндекс

VadimKHL

Новичок
Сообщения
155
Репутация
0
Добрый вечер!
Подскажите, как исправить кодировку русских символов в ответном запросе GET. В ответ приходит наподобие такого:
ÐодÑвеÑдиÑе, ÑÑо запÑоÑÑ Ð¾ÑпÑавлÑлÐ

Код:
Код:
Global Const $HTTP_STATUS_OK = 200

Global $sGet = HttpGet('https://translate.yandex.ru/', 'source_lang=en&target_lang=ru&text=Hello%20World.')
FileWrite("Out.html", String($sGet))

Exit

Func HttpGet($sURL, $sData = "")
Local $oHTTP = ObjCreate("WinHttp.WinHttpRequest.5.1")

$oHTTP.Open("GET", $sURL & "?" & $sData, False)
If (@error) Then Return SetError(1, 0, 0)

$oHTTP.Send()
If (@error) Then Return SetError(2, 0, 0)

If ($oHTTP.Status <> $HTTP_STATUS_OK) Then Return SetError(3, 0, 0)

Return SetError(0, 0, $oHTTP.ResponseText)
EndFunc
 

InnI

AutoIT Гуру
Сообщения
4,922
Репутация
1,432
 

Andrey_A

Продвинутый
Сообщения
325
Репутация
68
Yandex давно стал платным, ранее можно было использовать бесплатный ключ для точного перевода, сейчас нет
Напрямую бить в https://translate.yandex.ru/ не имеет смысла. В Yandex есть платное Api - платить и разбираться...
Лучше смотреть в пока беплатное - в сторону translate.google.com или Bing (нужен старый бесплатный ключ), где можно указывать направление перевода и текст, и далее получать то что нужно без крокозябр
Пример с Google без особых проверок объектов, текста - можете сами повставлять.
Код:
#include <Encoding.au3>
$sText='Hello World'
$sTr=_GoogleTranslateString($sText,'en|ru')
MsgBox(4096,'Переменная $sTr',$sTr)
$sText='Мороз и солнце; день чудесный!'&@CRLF& _
'Еще ты дремлешь, друг прелестный -'&@CRLF& _
'Пора, красавица, проснись:'&@CRLF& _
'Открой сомкнуты негой взоры'&@CRLF& _
'Навстречу северной Авроры,'&@CRLF& _
'Звездою севера явись!'
$sTr=_GoogleTranslateString($sText,'ru|en')
MsgBox(4096,'Переменная $sTr',$sTr)

Func _GoogleTranslateString(ByRef $sText,$vTag=-1)
  Local $R=StringSplit($vTag=-1? 'auto|en': $vTag,'|'),$b=ObjCreate('MSXML2.XMLHTTP'),$sLine,$tmp=_Encoding_URLToHex($sText)
  $b.Open('POST','http://translate.google.com/translate_a/single',0)
  $b.SetRequestHeader('Content-Type','application/x-www-form-urlencoded')
  $b.Send('client=qlt&dt=bd&dt=t&sl='&$R[1]&'&tl='&$R[2]&'&q='&$tmp)
  If $b.Status-200 Then Return
  $R=StringSplit($b.ResponseText,']]],["',1)
  For $i=1 To $R[0]
    $aRet=StringSplit($R[$i],'","',1)
    $sLine&=$aRet[1]
    If 4=$aRet[0]Then $sLine&=StringSplit($aRet[2],'],["',1)[2]
  Next
  Return StringReplace(StringReplace(StringReplace(StringTrimLeft(StringRegExpReplace(StringRegExpReplace($sLine,'(\\r\\n|\\r|\\n)+',@CRLF),'\\([&<>"])','$1'),4),'\u003e','>'),'\u003c','<'),'\u0026','&')
EndFunc
 
Последнее редактирование:

SealAlbinos

Продвинутый
Сообщения
154
Репутация
57
Yandex давно стал платным, ранее можно было использовать бесплатный ключ для точного перевода, сейчас нет
Напрямую бить в https://translate.yandex.ru/ не имеет смысла. В Yandex есть платное Api - платить и разбираться...
Лучше смотреть в пока беплатное - в сторону translate.google.com или Bing (нужен старый бесплатный ключ), где можно указывать направление перевода и текст, и далее получать то что нужно без крокозябр
Пример с Google без особых проверок объектов, текста - можете сами повставлять.
Код:
#include <Encoding.au3>
$sText='Hello World'
$sTr=_GoogleTranslateString($sText,'en|ru')
MsgBox(4096,'Переменная $sTr',$sTr)
$sText='Мороз и солнце; день чудесный!'&@CRLF& _
'Еще ты дремлешь, друг прелестный -'&@CRLF& _
'Пора, красавица, проснись:'&@CRLF& _
'Открой сомкнуты негой взоры'&@CRLF& _
'Навстречу северной Авроры,'&@CRLF& _
'Звездою севера явись!'
$sTr=_GoogleTranslateString($sText,'ru|en')
MsgBox(4096,'Переменная $sTr',$sTr)

Func _GoogleTranslateString(ByRef $sText,$vTag=-1)
  Local $R=StringSplit($vTag=-1? 'auto|en': $vTag,'|'),$b=ObjCreate('MSXML2.XMLHTTP'),$sLine,$tmp=_Encoding_URLToHex($sText)
  $b.Open('POST','http://translate.google.com/translate_a/single',0)
  $b.SetRequestHeader('Content-Type','application/x-www-form-urlencoded')
  $b.Send('client=qlt&dt=bd&dt=t&sl='&$R[1]&'&tl='&$R[2]&'&q='&$tmp)
  If $b.Status-200 Then Return
  $R=StringSplit($b.ResponseText,']]],["',1)
  For $i=1 To $R[0]
    $aRet=StringSplit($R[$i],'","',1)
    $sLine&=$aRet[1]
    If 4=$aRet[0]Then $sLine&=StringSplit($aRet[2],'],["',1)[2]
  Next
  Return StringReplace(StringReplace(StringReplace(StringTrimLeft(StringRegExpReplace(StringRegExpReplace($sLine,'(\\r\\n|\\r|\\n)+',@CRLF),'\\([&<>"])','$1'),4),'\u003e','>'),'\u003c','<'),'\u0026','&')
EndFunc
Не знаю в чем проблемы с бесплатным API, но его очень легко обойти, а ваш способ с гуглом не идеален, так как не используется ИИ и перевод выходит кривой и совершенно не точный (просто сравните как на самом сайте и как у вас в скрипте)

Код:
#include "Json.au3"
$Config = @ScriptDir & "\Config.ini"
$oHTTP = ObjCreate("winhttp.winhttprequest.5.1")
$ID = IniRead(@ScriptDir & "\Config.ini", "Key", "ID", "")
if $ID = "" Then _GetSID()

MsgBox(0,"",_Translate("Select sandbox, press T, spawn characters"))

Func _Translate($Text)
    $oHTTP.Open("GET", "https://translate.yandex.net/api/v1/tr.json/detect?sid="&$ID&"-0-0&srv=tr-text&text="&$Text&"")
    $oHTTP.SetRequestHeader("Content-Type", "application/json; charset=utf-8")
    $oHTTP.Send()
    $sReceived = $oHTTP.ResponseText
    $iStatus = $oHTTP.Status
    $Json = Json_Decode(String($sReceived))
    If $iStatus = 403 Then
        _GetSID()
    ElseIf $iStatus = 200 Then
        $lg = Json_ObjGet($Json, "lang")
    EndIf

    $oHTTP.Open("POST", "https://translate.yandex.net/api/v1/tr.json/translate?id="&$ID&"-0-0&srv=tr-text&text="&$Text&"&lang="&$lg&"-ru&reason=auto&format=text")
    $oHTTP.SetRequestHeader("Content-Type", "application/json; charset=utf-8")
    $oHTTP.Send()
    $sReceived = $oHTTP.ResponseText
    $iStatus = $oHTTP.Status
    $Json = Json_Decode(String($sReceived))

    If $iStatus = 403 Then
        _GetSID()
    ElseIf $iStatus = 200 Then
        $ReturnText = Json_Get($Json,'["text"][0]')
    EndIf

    Return $ReturnText
EndFunc

Func _GetSID()
    $oHTTP.Open("GET", "https://translate.yandex.ru", False)
    $oHTTP.Send()
    $sReceived = $oHTTP.ResponseText
    $iStatus = $oHTTP.Status
    If $iStatus = 200 Then
        $reqid = StringRegExp($oHTTP.ResponseText, "Ya.reqid = '(.*?)';", 3)
        If IsArray($reqid) then
            IniWrite(@ScriptDir & "\Config.ini", "Key", "ID", $reqid[0])
        Else
            MsgBox(0,"Ошибка","не удалось получить ID")
        EndIf
        $ID = IniRead(@ScriptDir & "\Config.ini", "Key", "ID", "")
    EndIf
EndFunc
 

Вложения

  • Json.au3
    22.9 КБ · Просмотры: 7
Последнее редактирование:

Andrey_A

Продвинутый
Сообщения
325
Репутация
68
и перевод выходит кривой и совершенно не точный (просто сравните как на самом сайте и как у вас в скрипте)
Вы так говорите, как будто я все это перевожу... в своё время было обрублено все бесплатное в Yandex
Что касается качества перевода - везде есть косяки...
Что касается вашего кода, то проблема с большим текстом , а переносы строк где?
Код:
#include "Json.au3"
$Config = @ScriptDir & "\Config.ini"
$oHTTP = ObjCreate("winhttp.winhttprequest.5.1")
$ID = IniRead(@ScriptDir & "\Config.ini", "Key", "ID", "")
if $ID = "" Then _GetSID()

$sText='Мороз и солнце; день чудесный!'&@CRLF& _
'Еще ты дремлешь, друг прелестный -'&@CRLF& _
'Пора, красавица, проснись:'&@CRLF& _
'Открой сомкнуты негой взоры'&@CRLF& _
'Навстречу северной Авроры,'&@CRLF& _
'Звездою севера явись!'
$sTr=_Translate($sText)
MsgBox(4096,'Переменная $sTr',$sTr)

; MsgBox(0,"",_Translate("Select sandbox, press T, spawn characters"))

Func _Translate($Text)
    $oHTTP.Open("GET", "https://translate.yandex.net/api/v1/tr.json/detect?sid="&$ID&"-0-0&srv=tr-text&text="&$Text&"")
    $oHTTP.SetRequestHeader("Content-Type", "application/json; charset=utf-8")
    $oHTTP.Send()
    $sReceived = $oHTTP.ResponseText
    $iStatus = $oHTTP.Status
    $Json = Json_Decode(String($sReceived))
    If $iStatus = 403 Then
        _GetSID()
    ElseIf $iStatus = 200 Then
        $lg = Json_ObjGet($Json, "lang")
    EndIf

    $oHTTP.Open("POST", "https://translate.yandex.net/api/v1/tr.json/translate?id="&$ID&"-0-0&srv=tr-text&text="&$Text&"&lang="&$lg&"-en&reason=auto&format=text")
    $oHTTP.SetRequestHeader("Content-Type", "application/json; charset=utf-8")
    $oHTTP.Send()
    $sReceived = $oHTTP.ResponseText
    $iStatus = $oHTTP.Status
    $Json = Json_Decode(String($sReceived))

    If $iStatus = 403 Then
        _GetSID()
    ElseIf $iStatus = 200 Then
        $ReturnText = Json_Get($Json,'["text"][0]')
    EndIf

    Return $ReturnText
EndFunc

Func _GetSID()
    $oHTTP.Open("GET", "https://translate.yandex.ru", False)
    $oHTTP.Send()
    $sReceived = $oHTTP.ResponseText
    $iStatus = $oHTTP.Status
    If $iStatus = 200 Then
        $reqid = StringRegExp($oHTTP.ResponseText, "Ya.reqid = '(.*?)';", 3)
        If IsArray($reqid) then
            IniWrite(@ScriptDir & "\Config.ini", "Key", "ID", $reqid[0])
        Else
            MsgBox(0,"Ошибка","не удалось получить ID")
        EndIf
        $ID = IniRead(@ScriptDir & "\Config.ini", "Key", "ID", "")
    EndIf

Да и зачем Json.au3 - легко без него парсингуется, быстрее и проще , не таща в скрипт ненужные функции.
Но за идею спасибо!
 
Последнее редактирование:

SealAlbinos

Продвинутый
Сообщения
154
Репутация
57
Вы так говорите, как будто я все это перевожу... в своё время было обрублено все бесплатное в Yandex
Что касается качества перевода - везде есть косяки...
Что касается вашего кода, то проблема с большим текстом , а переносы строк где?
Да и зачем Json.au3 - легко без него парсингуется, быстрее и проще , не таща в скрипт ненужные функции.
Код:
#include "Json.au3"
$Config = @ScriptDir & "\Config.ini"
$oHTTP = ObjCreate("winhttp.winhttprequest.5.1")
$ID = IniRead(@ScriptDir & "\Config.ini", "Key", "ID", "")
if $ID = "" Then _GetSID()

$sText='Мороз и солнце; день чудесный!'&@CRLF& _
'Еще ты дремлешь, друг прелестный -'&@CRLF& _
'Пора, красавица, проснись:'&@CRLF& _
'Открой сомкнуты негой взоры'&@CRLF& _
'Навстречу северной Авроры,'&@CRLF& _
'Звездою севера явись!'
$sTr=_Translate($sText)
MsgBox(4096,'Переменная $sTr',$sTr)

; MsgBox(0,"",_Translate("Select sandbox, press T, spawn characters"))

Func _Translate($Text)
    $oHTTP.Open("GET", "https://translate.yandex.net/api/v1/tr.json/detect?sid="&$ID&"-0-0&srv=tr-text&text="&$Text&"")
    $oHTTP.SetRequestHeader("Content-Type", "application/json; charset=utf-8")
    $oHTTP.Send()
    $sReceived = $oHTTP.ResponseText
    $iStatus = $oHTTP.Status
    $Json = Json_Decode(String($sReceived))
    If $iStatus = 403 Then
        _GetSID()
    ElseIf $iStatus = 200 Then
        $lg = Json_ObjGet($Json, "lang")
    EndIf

    $oHTTP.Open("POST", "https://translate.yandex.net/api/v1/tr.json/translate?id="&$ID&"-0-0&srv=tr-text&text="&$Text&"&lang="&$lg&"-en&reason=auto&format=text")
    $oHTTP.SetRequestHeader("Content-Type", "application/json; charset=utf-8")
    $oHTTP.Send()
    $sReceived = $oHTTP.ResponseText
    $iStatus = $oHTTP.Status
    $Json = Json_Decode(String($sReceived))

    If $iStatus = 403 Then
        _GetSID()
    ElseIf $iStatus = 200 Then
        $ReturnText = Json_Get($Json,'["text"][0]')
    EndIf

    Return $ReturnText
EndFunc

Func _GetSID()
    $oHTTP.Open("GET", "https://translate.yandex.ru", False)
    $oHTTP.Send()
    $sReceived = $oHTTP.ResponseText
    $iStatus = $oHTTP.Status
    If $iStatus = 200 Then
        $reqid = StringRegExp($oHTTP.ResponseText, "Ya.reqid = '(.*?)';", 3)
        If IsArray($reqid) then
            IniWrite(@ScriptDir & "\Config.ini", "Key", "ID", $reqid[0])
        Else
            MsgBox(0,"Ошибка","не удалось получить ID")
        EndIf
        $ID = IniRead(@ScriptDir & "\Config.ini", "Key", "ID", "")
    EndIf
Не вижу у себя никаких проблем с большим текстом, когда пример был показан на то, что яндекс нормально работает и используется нормальный перевод, а не бесплатный api
про json, зачем изобретать велосипед, когда уже все сделано и адаптированно
про тот же гугл, то можно получить куда более качественный перевод используя готовый запрос к их сервису (пример: mymemory.translated)

Код:
#include "Json.au3"

MsgBox(0,"",_Translate("Select sandbox, press T, spawn characters"))

Func _Translate($Text)
    $oHTTP = ObjCreate("winhttp.winhttprequest.5.1")
    $oHTTP.Open("GET", "https://mymemory.translated.net/api/ajaxfetch?q="&$Text&"&langpair=sq-AL|ru-GB&mtonly=1")
    $oHTTP.SetRequestHeader("Content-Type", "application/json; charset=utf-8")
    $oHTTP.Send()
    $sReceived = $oHTTP.ResponseText
    $Json = Json_Decode(String($sReceived))
    $ReturnText = Json_Get($Json,'["responseData"][translatedText]')
   Return $ReturnText
EndFunc
 
Последнее редактирование:

Andrey_A

Продвинутый
Сообщения
325
Репутация
68
Не вижу у себя никаких проблем с большим текстом,
Вы теcтируете на одной строке. А где же переводы строк при многострочном тексте?
И где вставлять направленный перевод типа 'ru-en' - это что? 'sq-AL|ru-GB&mtonly=1'
 
Последнее редактирование:

SealAlbinos

Продвинутый
Сообщения
154
Репутация
57
Вы теcтируете на одной строке. А где же переводы строк при многострочном тексте?
И где вставлять направленный перевод типа 'ru-en' - это что? 'sq-AL|ru-GB&mtonly=1'

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

langpair=sq-AL|ru
sq-AL - автодетект языка
ru - язык на который переводим
 
Последнее редактирование:
Автор
V

VadimKHL

Новичок
Сообщения
155
Репутация
0
ООО, всем спасибо за инфу и примеры, буду разбираться...

Вообще конечная идея делать скрин экрана, обрезать нижнию часть где сабтитры, далее распознавать из картинки текст, далее его переводить, далее его озвучивать. Но по расценкам яндекса похоже по играть 4 часа и если скрины отсылать каждые 1 или 3 секунды будет безбожно дорого(((((
 

SealAlbinos

Продвинутый
Сообщения
154
Репутация
57
ООО, всем спасибо за инфу и примеры, буду разбираться...

Вообще конечная идея делать скрин экрана, обрезать нижнию часть где сабтитры, далее распознавать из картинки текст, далее его переводить, далее его озвучивать. Но по расценкам яндекса похоже по играть 4 часа и если скрины отсылать каждые 1 или 3 секунды будет безбожно дорого(((((
Распознование лучше использовать от гугла (через гугл доки)
Подобное делал как то, что гугл распознает текст и выдает его, а яд уже переводит (от гугла намного лучше OCR)
 
Последнее редактирование:

musicstashall

Знающий
Сообщения
322
Репутация
7

SealAlbinos

Продвинутый
Сообщения
154
Репутация
57
Этот вариант еще рабочий на сегодняшний день? У меня чего-то не получается
Рабочий, возможно что то с получением ID, подправь его и должно быть все ок
Возможно нужно указать дополнительные загловки
 
Последнее редактирование:

SealAlbinos

Продвинутый
Сообщения
154
Репутация
57
Там ID не парсится. Может вообще по данному URL его нет.
Проверил и все окей
и как дописал выше, изменилось что нужны доп заголовки при отправке запроса
если много раз пытались сделать (получить ID через скрипт), то скорее всего яд кинул в блок и якобы просит указать капчу
тут или делать интерфейс и указывать капчу или ждать какое то время (или выдрать ID самому с браузера и прописать в конфиге)
 

musicstashall

Знающий
Сообщения
322
Репутация
7
если много раз пытались сделать (получить ID через скрипт), то скорее всего яд кинул в блок и якобы просит указать капчу
Только самый первый вызов дает ответ, все последующие с данного IP-адреса выбрасывает на капчу. VPN помогает только на один вызов. Мож я что-то неправильно делаю? Какие заголовки нужны еще?? Я не знаю. Темный лес)
можно получить куда более качественный перевод используя готовый запрос к их сервису (пример: mymemory.translated)
После 10 обращений, такой ответ:
HTML:
MYMEMORY WARNING: YOU USED ALL AVAILABLE FREE TRANSLATIONS FOR TODAY. NEXT AVAILABLE IN  01 HOURS 26 MINUTES 14 SECONDS VISIT HTTPS://MYMEMORY.TRANSLATED.NET/DOC/USAGELIMITS.PHP TO TRANSLATE MORE

Нашел проект яндекс переводчика на питоне, работает через прокси, автор заверяет, что никаких ограничений нет. GitHub
 
Последнее редактирование:

SealAlbinos

Продвинутый
Сообщения
154
Репутация
57
Только самый первый вызов дает ответ, все последующие с данного IP-адреса выбрасывает на капчу. VPN помогает только на один вызов. Мож я что-то неправильно делаю? Какие заголовки нужны еще?? Я не знаю. Темный лес)

После 10 обращений, такой ответ:
HTML:
MYMEMORY WARNING: YOU USED ALL AVAILABLE FREE TRANSLATIONS FOR TODAY. NEXT AVAILABLE IN  01 HOURS 26 MINUTES 14 SECONDS VISIT HTTPS://MYMEMORY.TRANSLATED.NET/DOC/USAGELIMITS.PHP TO TRANSLATE MORE

Нашел проект яндекс переводчика на питоне, работает через прокси, автор заверяет, что никаких ограничений нет. GitHub
За mymemory.translated сложно сказать, ибо могли сделать ограничение и если это так, то нужно будет уже искать альтернативы
Что касается яндекса, то я про
Код:
$oHTTP.SetRequestHeader

Посмотрите через браузер все заголовки и методом перебора (или просто разом все) и укажите их в скрипте и после должно быть все ок. Они могли добавить проверку на наличие к примеру referer или тому подобного
P.s Про яндекс же, то там ТОЧНО не нужен никакой прокси, для работы нужен только ID, который держится около 3-4 дней, а потом просто обновляется методом предоставленным в скрипте
 
Последнее редактирование:

musicstashall

Знающий
Сообщения
322
Репутация
7
Последнее редактирование:

SealAlbinos

Продвинутый
Сообщения
154
Репутация
57
Самую малость мне обьясните, как и чем посмотреть «через браузер»? Как это делается?
Открываешь сеть браузера (обычно это F12, а там вкладка “сеть“) и смотришь пакеты которые браузер получает от сайта и как собственно там выглядят заголовки и в точности такие же переписываешь в скрипт
 
Верх