не могу найти адрес аудио-файла.а в чем сложность? найти в DOM путь к файлу, указать спаршенный урл в GET запросе
https://api-secure.solvemedia.com/papi/media?c=2@D-u7ZI7ObqfedKfx3nt7WYN5sL8MmqK3@UvTExNR1MRgENU8bgrS.HH9APTC4lJjo7lc4TYOvQzhIEJcPrQBILXZzzsRQW1QSQWI4LtqlDuncPN-e.Ay950no-VoB5KJl93K2GfdoZqDfztIao7.xgoSLEl5oxs1EtcKOTsq8JPYVjLPGWPb2C.twTV0YzSfSBpzJ6lhgFPXhu9x16h60b3qmCL.qgz3GFsgJM1G78lKXTS5UnOFkDqWQI6uSmoR.sImIsPMI2zbisPiyNv3MOISrrUlBEtfWx4alu5vNtMMmSEVcgrS6gA
это не помогает. ссылка точно такого же вида и точно также ГЕТ запрос ничего не качает путногоВыключи плагины Flash/Java/SilverLight.
Потом начнет появляться ссылка на аудио файл.
http://zennolab.com/wiki/ru:addons:capmonster:sm-audio
здесь внизу об этом написано
страницу перезагружаете после того как плагины отключили?это не помогает. ссылка точно такого же вида и точно также ГЕТ запрос ничего не качает путного
да. вы сами попробуйте гет-запросом скачать аудио-файл по такой ссылке, как в вашем примерестраницу перезагружаете после того как плагины отключили?
Проблема описана выше, ГЕТ запрос не выкачивает капчу. В этом плане ничего не изменилось. ГЕТом ничего не выкачать. Надо идти через нажатие кнопки. Собственно решение, как получить эту капчу, было описано вами же в другой ветке.В чем была проблема?
Получается как не крути, а из за капчи, прийдется к шаблону который на пост гет запросах, прикручивать загрузку страницы в браузере? Беда печаль =(Проблема описана выше, ГЕТ запрос не выкачивает капчу. В этом плане ничего не изменилось. ГЕТом ничего не выкачать. Надо идти через нажатие кнопки. Собственно решение, как получить эту капчу, было описано вами же в другой ветке.
1. http://api.solvemedia.com/papi/challenge.script?k=(Ключ формы капчи)
2. http://api.solvemedia.com/papi/_puzzle.js
3. http://api.solvemedia.com/papi/_challenge.js?k=(Ключ формы капчи);
f=_ACPuzzleUtil.callbacks%5B0%5D; // Есть в ответе puzzle.js - _ACPuzzleUtil.callbacks[0] (%5B0%5D - это [0])
l=en; // Есть в ответе первого запроса - Язык капчи
t=img; // Есть в ответе первого запроса - Тип капчи
s=standard; // Есть в ответе первого запроса - Размер size
c=js,h5c,h5ct,svg,h5v,v/ogg,v/webm,h5a,a/mp3,a/ogg,ua/firefox,ua/firefox47,os/nt,os/nt6.1,expand,fwv/PCir2g.islh74,jslib/jquery,htmlplus;
// Есть в ответе puzzle.js - Но надо составлять
am=pFs8xmXuDXWYc4pTZe4NdQ; // Есть в ответе первого запроса
ca=script; // Есть в ответе первого запроса
ts=1482543039; // Время UNIX - Текущее на данный момент
ct=1482543856; // Есть в ответе первого запроса - Время UNIX - Старое
th=white; // Есть в ответе первого запроса - Тема оформления
r=0.3989319945381731 // Mach.Random() - Случайное число от 0 до 1 из скрипта puzzle.js
var ACPuzzleOptions;
var ACPuzzleInfo = {
ckey: '(Ключ формы капчи)',
protocol: !window.location.protocol.match(/^https?:$/) ? 'http:' : '',
apiserver: '//api.solvemedia.com',
mediaserver: '//api.solvemedia.com',
magic: 'pFs8xmXuDXWYc4pTZe4NdQ',
chalapi: 'script',
chalstamp: 1482543856,
lang: 'en',
size: 'standard',
theme: 'white',
type: 'img',
onload: function(){ ACPuzzle.script_init() }
};
document.write('<' + 'scr' + 'ipt type="text/javascript" s' + 'rc="' +
(ACPuzzleInfo.protocol || '') + ACPuzzleInfo.apiserver + '/papi/_puzzle.js"><' + '/scr' + 'ipt' + '>');
Прочитал, вроде порядок действий норм, где у тебя там ошибка, так проблематично сказать.Попытался скачать аудио-капчу SolveMedia через GET запрос. В браузере загрузил страничку с капчей и увидел три GET запроса капчи. Третий запрос формируется на основе двух первых.
...
надеюсь тебе не заспамили личку фразами "есть готовое решение?"Прочитал, вроде порядок действий норм, где у тебя там ошибка, так проблематично сказать.
В общем порядок действий такой.
1. Get запрос формата http://api.solvemedia.com/papi/challenge.script?k=HmjWW-mdW2kwRzrXIOURB3zqUBk5aV0p
2. Из ответа вытаскиваются данные ckey, magic, chalapi, chalstamp, lang, size, theme, type,
3. Get запрос http://api.solvemedia.com/papi/_puzzle.js
Из полученного скрипта вытаскиваем ts, а также генерим с, на основе алгоритма как в скрипте
4. Get запрос на http://api.solvemedia.com/papi/_challenge.js? + все параметры которые наковыряли, type=img, _str это и есть с, которую генерили
5. Из ответа вытаскиваем chid и mediatype
6. Проверка что лежит в mediatype, если там нихрена - бан по ip
7. Повторяем запрос из пункта 4 но теперь уже type=aud, остальное все без изменений(за исключением рандома для r), затем пункт 5, чтобы получить новый chid, на mediatype уже похер.
8. Запрос аудио. Вот тут то и нужен chid(вообще он нужен не только для аудио), который меняется при каждом запросе.
Получаем ответ в виде массива байтов.
9. Скармливаем монстру
10. Профит!
Пункты 4, 5, 6, 7.
Можно сразу отправлять запрос с type=aud, без первого запроса с img.
Но я бы так не стал делать, по нескольким причинам.
Первая. Т.к первый запрос из браузера автоматом уходит именно с img, и только потом, когда переключается капча на аудио, уходит с aud, т.е если не делать первого запроса с img, это лишнее палево.
Вторая. При первом запросе с img, там может прийти несколько вариантов ответов, и некоторые очень интересные, но это уже отдельная тема и не относится к аудио.
chid, постоянно надо получать новый, при каждом новом запросе с aud или img.
Т.е взяли аудио, не разгадалось/не подошло, посылается новый запрос для получения нового chid, чтобы скачать новое аудио.
Но я так не рекомендую делать. Ip моментально задрачивается, качество аудио становится еще хуже чем было(которое и так пздц), что наврядли повысит процент успешного разгадывания.
А это разве не готовое?надеюсь тебе не заспамили личку фразами "есть готовое решение?"
ну для меня это почти готовое решение, для 95% форума тут ниче непонятно даже, так что уж точно щас начнется смак "покажи", да "научи"А это разве не готовое?
Мне бы кто такой гайд подкинул, когда я SM капчу ковырял.
Вся аналитическая работа проделана, расписано что, откуда, куда, и почему, шаг за шагом.
Осталось только чутка поднапрячься и собрать все это.
Ну а кому уж совсем лениво, ок, пусть пишут в личку, поди договоримся, напрягусь за них.
Что бы заработал 3, 4 и 5 запрос. Делаем костыль, заменяем 3 GET запрос, на POST запрос и 4 GET запрос, на POST запрос.
url post запроса: (http://api.solvemedia.com/papi/challenge.script?)
Остальное в из GET запроса в данные POST запроса. А 5 запрос как обычно GET запросом сохраняем аудио файл.
public class SolveMediaCaptcha
{
private enum RandomType
{
Num,
Chars,
NumAndChars
}
/// <summary>
/// Тип прокси.
/// </summary>
public enum ProxyTypeEnum
{
Http,
Socks
}
/// <summary>
/// Ответ распознавания или описание ошибки.
/// </summary>
public string Answer { get; private set; }
/// <summary>
/// Токен распознанной капчи
/// </summary>
public string AnswerToken { get; private set; }
/// <summary>
/// Прокси, в виде ip:port или name:passoword@ip:port
/// </summary>
public string Proxy { get; set; }
/// <summary>
/// Тип прокси. По умолчанию http.
/// </summary>
public ProxyTypeEnum ProxyType { get; set; }
/// <summary>
/// UserAgent
/// </summary>
public string UserAgent { get; set; }
/// <summary>
/// Referer, урл сайта на котором находится капча
/// </summary>
public string Referer { get; set; }
/// <summary>
/// Адрес CM, в виде ip
/// </summary>
public string CapMonsterAddress { get; set; }
/// <summary>
/// Ключ(если есть) CM
/// </summary>
public string CapMonsterKey { get; set; }
private readonly string _siteKey;
private CookieDictionary _cookieDictionary = new CookieDictionary();
public SolveMediaCaptcha(string siteKey)
{
_siteKey = siteKey;
Answer = "";
AnswerToken = "";
Proxy = "";
ProxyType = ProxyTypeEnum.Http;
UserAgent = "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/52.0.2743.116 Safari/537.36";
Referer = "";
}
/// <summary>
/// Распознать капчу.
/// </summary>
/// <returns>True, при успехе, в Answer будет записан ответ. False, при неуспехе, в Answer будет записано описание ошибки.</returns>
public bool Recognize()
{
string response = ResponseFirst();
if (response == null) return false;
GetValuesFirst(response);
response = ResponsePuzzle();
if (response == null) return false;
if (!GetValuesPuzzle(response)) return false;
response = ResponseChallenge("img");
if (response == null) return false;
if (!GetValuesChallenge(response)) return false;
if (_mediatype == "")
{
Answer = "ip ban";
return false;
}
response = ResponseChallenge("aud");
if (response == null) return false;
if (!GetValuesChallenge(response)) return false;
var mp3Array = ResponseGetAudio();
if (mp3Array == null) return false;
if (RecognizeAudio(mp3Array)) return true;
return false;
}
private string ResponseToString(string url)
{
var res = (string)SendGet(url, "ToString");
if (string.IsNullOrEmpty(res)) return null;
return res;
}
private byte[] ResponseToByteArray(string url)
{
var res = (byte[])SendGet(url, "ToBytes");
if (res == null) return null;
return res;
}
private object SendGet(string url, string convert)
{
object response = null;
try
{
var request = new HttpRequest();
request.Proxy = SetProxy();
request.EnableEncodingContent = true;
request.ConnectTimeout = 15000;
request.Cookies = _cookieDictionary;
request.UserAgent = UserAgent;
request.AllowAutoRedirect = true;
request.MaximumAutomaticRedirections = 3;
request.KeepAlive = true;
request.Referer = Referer;
request["Accept"] = "*/*";
request["Accept-Language"] = "ru-RU,ru;q=0.8,en-US;q=0.6,en;q=0.4";
if (convert == "ToString")
{
response = request.Get(url).ToString();
}
if (convert == "ToBytes")
{
response = request.Get(url).ToBytes();
}
request.Close();
}
catch (HttpException e)
{
switch (e.Status)
{
case HttpExceptionStatus.Other:
Answer = "Неизвестная ошибка";
break;
case HttpExceptionStatus.ProtocolError:
Answer = Answer = "Код состояния: " + (int)e.HttpStatusCode;
break;
case HttpExceptionStatus.ConnectFailure:
Answer = "Не удалось соединиться с HTTP-сервером";
break;
case HttpExceptionStatus.SendFailure:
Answer = "Не удалось отправить запрос HTTP-серверу";
break;
case HttpExceptionStatus.ReceiveFailure:
Answer = "Не удалось загрузить ответ от HTTP-сервера";
break;
}
}
return response;
}
private string ResponseFirst()
{
var url = "http://api.solvemedia.com/papi/challenge.script?k=" + _siteKey;
var response = ResponseToString(url);
if (response == null)
{
return null;
}
var result = response;
return result;
}
private string _cKey;
private string _magic;
private string _chalapi;
private string _chalstamp;
private string _lang;
private string _size;
private string _theme;
private string _type;
private void GetValuesFirst(string response)
{
var pattern = "(?<=var\\ ACPuzzleInfo\\ =\\ \\{)[\\w\\W]*(?=};)";
var match = Regex.Match(response, pattern).Value.Trim('\r', '\n');
var split = match.Split(',');
var dic = new Dictionary<string, string>();
foreach (var s in split)
{
var str = s.Trim('\n', '\r', ' ');
var innerSplit = str.Split(':');
dic.Add(innerSplit[0], innerSplit[1].Trim('\t', ' ', '\''));
}
_cKey = dic["ckey"];
_magic = dic["magic"];
_chalapi = dic["chalapi"];
_chalstamp = dic["chalstamp"];
_lang = dic["lang"];
_size = dic["size"];
_theme = dic["theme"];
_type = dic["type"];
}
private string ResponsePuzzle()
{
var url = "http://api.solvemedia.com/papi/_puzzle.js";
var response = ResponseToString(url);
if (response == null)
{
return null;
}
var result = response;
return result;
}
private string _str;
private string _ts;
private bool GetValuesPuzzle(string response)
{
var patternKey = "(?<=caps=caps\\+',).*?(?='\\+'\\.'\\+String\\.fromCharCode)";
var patternTs = "(?<=;ts=).*(?='\\+')";
var match = Regex.Match(response, patternKey).Value;
if (match == "")
{
Answer = "error GetValuesPuzzle";
return false;
}
var key = match;
match = Regex.Match(response, patternTs).Value;
if (match == "")
{
Answer = "error GetValuesPuzzle";
return false;
}
_ts = match;
_str = string.Format(
"c=js,h5c,h5ct,svg,h5v,v/h264,v/ogg,v/webm,h5a,a/mp3,a/ogg," +
"ua/chrome," +
"ua/chrome52," +
"os/nt," +
"os/nt6.1," +
"expand,swf22,swf22.0,swf," +
"{0}," +
"jslib/jquery,htmlplus;",
key + "." + GenerateRandom(RandomType.Chars, 4) + new Random().Next(11, 100)); // "fwv/M.Mosg.hidi11"
return true;
}
private string ResponseChallenge(string type)
{
var url = string.Format(
"http://api.solvemedia.com/papi/_challenge.js?" +
"k={0};" +
"f=_ACPuzzleUtil.callbacks%5B0%5D;" +
"l={1};" +
"t={2};" +
"s={3};" +
_str +
"am={4};" +
"ca={5};" +
"ts={6};" +
"ct={7};" +
"th={8};" +
"r=0." + GenerateRandom(RandomType.Num, 16), // 0.3483017170539391
_cKey,
_lang,
type,
_size,
_magic,
_chalapi,
_ts,
_chalstamp,
_theme);
var response = ResponseToString(url);
if (response == null)
{
return null;
}
var result = response;
return result;
}
private string _chid;
private string _mediatype;
private bool GetValuesChallenge(string response)
{
try
{
var pattern = "(?<=\"ACChallengeResult\":\\ \\{)[\\w\\W]*(?=\\ \"media_size\")";
var match = Regex.Match(response, pattern).Value.Trim('\r', '\n');
var split = match.Split(new[] { ",\n" }, StringSplitOptions.None);
_chid = split[0].Split(':')[1].Trim(' ', '"');
_mediatype = split[3].Split(':')[1].Trim(' ', '"');
}
catch (Exception e)
{
Answer = "error GetValuesChallenge";
return false;
}
return true;
}
private byte[] ResponseGetAudio()
{
var url = string.Format(
"http://api.solvemedia.com/papi/media?" +
"c={0};" +
"w=300;" +
"h=150;" +
"fg=000000;" +
"bg=f8f8f8",
_chid);
var response = ResponseToByteArray(url);
if (response == null)
{
return null;
}
return response;
}
private bool RecognizeAudio(byte[] mp3Array)
{
if (mp3Array.Length < 1000)
{
Answer = "bad mp3Array";
return false;
}
var recognize = CapMonsterRecognize(mp3Array, CapMonsterKey, CapMonsterAddress);
if (recognize == null) return false;
Answer = recognize;
AnswerToken = _chid;
return true;
}
private string CapMonsterRecognize(byte[] mp3Array, string key, string address)
{
try
{
var boundary = GenerateRandom(RandomType.NumAndChars, 15);
var mc = new MultipartContent(boundary)
{
{new StringContent("post"), "method"},
{new StringContent("19"), "soft_id"},
{new StringContent(key), "key"},
{new StringContent("ZennoLab.AudioSolveMedia"), "CapMonsterModule"},
{new BytesContent(mp3Array), "file", "Captcha.png", "audio/mp3"}
};
var request = new HttpRequest();
request.UserAgent = "TubeCast v1.0";
request["Accept"] = "*/*";
request["Accept-Language"] = "ru";
request.Proxy = SetProxy();
var response = request.Post(string.Format("http://{0}/in.php", address), mc).ToString();
request.Close();
if (response == "" || !response.Contains("OK"))
{
Answer = "CapMonster, error on post";
return null;
}
var id = response.Split('|')[1];
//---
request = new HttpRequest();
request.UserAgent = "TubeCast v1.0";
request["Accept"] = "*/*";
request["Accept-Language"] = "ru";
request.Proxy = SetProxy();
response = request.Get(string.Format("http://{0}/res.php?key={1}&action=get&id={2}", address, key, id)).ToString();
request.Close();
if (response == "" || !response.Contains("OK"))
{
Answer = "CapMonster, error on get";
return null;
}
return response.Split('|')[1];
}
catch (HttpException e)
{
switch (e.Status)
{
case HttpExceptionStatus.Other:
Answer = "Неизвестная ошибка";
break;
case HttpExceptionStatus.ProtocolError:
Answer = "Код состояния: " + (int)e.HttpStatusCode;
break;
case HttpExceptionStatus.ConnectFailure:
Answer = "Не удалось соединиться с HTTP-сервером";
break;
case HttpExceptionStatus.SendFailure:
Answer = "Не удалось отправить запрос HTTP-серверу";
break;
case HttpExceptionStatus.ReceiveFailure:
Answer = "Не удалось загрузить ответ от HTTP-сервера";
break;
}
}
catch (Exception e)
{
Answer = e.ToString();
}
return null;
}
private string GenerateRandom(RandomType type, int count)
{
char[] chars;
switch (type)
{
case RandomType.Num:
{
chars = "1234567890".ToCharArray();
break;
}
case RandomType.Chars:
{
chars = "abcdefghijklmnopqrstuvwxyz".ToCharArray();
break;
}
default:
{
chars = "1234567890abcdefghijklmnopqrstuvwxyz".ToCharArray();
break;
}
}
var buf = new StringBuilder();
var rnd = new Random();
for (var i = 0; i < count; i++)
{
buf.Append(chars[rnd.Next(chars.Length)]);
}
return buf.ToString();
}
private ProxyClient SetProxy()
{
if (Proxy == "") return null;
ProxyClient wp;
var split = Proxy.Split('@');
if (split.Length == 1)
{
var address = split[0].Split(':');
var ip = address[0];
var port = int.Parse(address[1]);
if (ProxyType == ProxyTypeEnum.Socks)
{
wp = new Socks5ProxyClient(ip, port);
}
else
{
wp = new HttpProxyClient(ip, port);
}
}
else
{
var credential = split[0].Split(':');
var address = split[1].Split(':');
var ip = address[0];
var port = int.Parse(address[1]);
var user = credential[0];
var password = credential[1];
if (ProxyType == ProxyTypeEnum.Socks)
{
wp = new Socks5ProxyClient(ip, port, user, password);
}
else
{
wp = new HttpProxyClient(ip, port, user, password);
}
}
return wp;
}
}
lang, size, theme, type - этот хлам вытаскивать не нужно. Он всегда один и тот же. Правда на кране Мовилбитс я встречал lang - es, хотя всюду он eng, но это роли не играет.2. Из ответа вытаскиваются данные ckey, magic, chalapi, chalstamp, lang, size, theme, type,
XKdYDtomrdIENU8bgrS8zX9APTC4lJjoVHVmZR.GHSjhE7.RI63KLRsRWzRv64S6sX-zSes4E560LdkVyQxuPOqqNnwJ31N1NmYoW4Lx8uTIPtEWBgyjcrboa0GWmFBql9RtxBvrQmwoxp1E8v9uGTI26rW3qjww2EaOMgRyF5R84P.8.1IkmXXNLGXK0yfGjjOZxmK4letnvDh8rNqBLih3uo0qln2vPS4DsuFv2d06bNoNTsChJx7ODQ5aB-TNr7XyIDxZvOQmSEVcgrS6gA*loveme
XKSpGtolXMYENU8bgrS7vH9APTC4lJjo5eKD.I1EsSenFhcWH-Wf0CYHMJQ2qLA6cBtoeScSmY0pK5c5bBmNaA1x3uiKdVeddTB.RWcKgBzaUfj9PKf6BxmYoCuyJNCN12cTWy3u.4Mo7GIkIgYS6iOUZUdq.TWZqVqnU-7F78-38w5OrHaBmydkVC5aBiKsP.da5gWdczcCJieah6qCU5uy8pGKEtAhUsd2TtJCjJZnKKwK0lXnqoAarBmtvF8kmuhwdjzWWV0mSEVcgrS6gA*loveme
XKeKzdomfxEENU8bgrS8kH9APTC4lJjosM-pOCI3IT.R-iozU93cTWZd0WsTmLLY4R-Ea-nQVCi42uMD9ahT.IFoBG6cENsWcyZILUNHGL5GHFmvGgbMS-xLv-VeLyqfZAM26qponY1yX0GXtkUg-AzItzRtRWYMytieeMLoU7qYo8HP3VcYXo69GUedcw0vUm9xsyYScqEM4sYKqDDN9Zn2Z37inSFD8Gf5fm67c6cIoK4TExivxjhN4mcNe5rw6csNd4XWOBQmSEVcgrS6gA*loveme