Пытаюсь спарсить сайт https://emex.ru. Собираю запрос так же, как он представлен в браузере:
public async Task<string> GetEventListData(string detailNum, string requestVerificationToken, string sessionId)
{
FormUrlEncodedContent content = new FormUrlEncodedContent(new[]
{
new KeyValuePair<string, string>("detailNum", detailNum),
new KeyValuePair<string, string>("loadingGroupId", ""),
new KeyValuePair<string, string>("packetId", "-1"),
new KeyValuePair<string, string>("locationId", "17883"),
new KeyValuePair<string, string>("deliveryType", ""),
new KeyValuePair<string, string>("isFirstLoading", "true"),
new KeyValuePair<string, string>("sessionId", sessionId),
new KeyValuePair<string, string>("latitude", "57.9984"),
new KeyValuePair<string, string>("longitude", "56.2591"),
new KeyValuePair<string, string>("geoCoordsType", "Location"),
new KeyValuePair<string, string>("__RequestVerificationToken", requestVerificationToken),
});
return await SendEventListRequest("/Find2/Find/FindByDetailNum", content);
}
И далее отправляю его:
public async Task<string> SendEventListRequest(string url, FormUrlEncodedContent content = null)
{
Uri baseAddress = new Uri("https://emex.ru");
CookieContainer cookieContainer = new CookieContainer();
foreach (string c in
"best-location=4481; __RequestVerificationToken=7OCgvyozf0gUnLj6ptYdjEQGf4mgcCLeQPno12tMQiDdK1Wnco07eeiK3YCtvBOPcWXdm3Nhg4LBx_bYoZS0uUXszoqMZNudJ4to1SnixjitRmyLEzmaXe3jpPqy16rk-b62di2CjGT6jHkWgU03GQ2; NSC_xxx.fnfy.sv=ffffffffc3a01c1f45525d5f4f58455e445a4a423652; _ga=GA1.2.1487574528.1538146273; _ym_uid=1538146273636665587; _ym_d=1538146273; current-location=17883; isBestLocationDetected=true; current-region-long-lat=%257B%2522Id%2522%253A1658%252C%2522Name%2522%253A%2522%25D0%259F%25D0%25B5%25D1%2580%25D0%25BC%25D1%258C%2522%252C%2522EmexName%2522%253A%2522%25D0%259F%25D0%25B5%25D1%2580%25D0%25BC%25D1%258C%2522%252C%2522Longitude%2522%253A56.234195%252C%2522Latitude%2522%253A58.010259%252C%2522AreaId%2522%253A1683%252C%2522AreaName%2522%253A%2522%25D0%259F%25D0%25B5%25D1%2580%25D0%25BC%25D1%2581%25D0%25BA%25D0%25B8%25D0%25B9%2520%25D0%25BA%25D1%2580%25D0%25B0%25D0%25B9%2522%252C%2522CountryId%2522%253A3%252C%2522CountryName%2522%253A%2522%25D0%25A0%25D0%25BE%25D1%2581%25D1%2581%25D0%25B8%25D1%258F%2522%257D; current-position=%257B%2522X%2522%253A%252256.2591%2522%252C%2522Y%2522%253A%252257.9984%2522%252C%2522type%2522%253A%2522Location%2522%252C%2522source%2522%253A%2522CurrentLocation%2522%252C%2522fixed%2522%253Afalse%257D; _gid=GA1.2.951665973.1538303681; _ym_isad=1"
.Split(';'))
cookieContainer.Add(baseAddress, new Cookie(c.Split('=')[0].Trim(), c.Split('=')[1].Trim()));
using (HttpClientHandler handler = new HttpClientHandler() /*{CookieContainer = cookieContainer}*/)
using (HttpClient client = new HttpClient(handler) {BaseAddress = baseAddress})
{
client.DefaultRequestHeaders.Add("User-Agent",
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.100 Safari/537.36");
HttpResponseMessage result = await client.PostAsync(url, content);
return await result.Content.ReadAsStringAsync();
}
}
В итоге, возвращается код 418 и сообщение "The custom error module does not recognize this error.". Пробовал добавить cookie, но эффекта нет. Как выйти решить проблему?
Вы зачем то закомментировали Cookie, вот тут:
using (HttpClientHandler handler = new HttpClientHandler() /*{CookieContainer = cookieContainer}*/)
Также очень не советую Вам делать что то вроде
foreach (string c in "best-location=4481...куча текста...".Split(';'))
cookieContainer.Add(baseAddress, new Cookie(c.Split('=')[0].Trim(), c.Split('=')[1].Trim()));
Во первых не нужно отправлять так много!
Во вторых, Cookie зачастую неизменны, меняются их значения, но не кол-во или что то подобное, зачем тогда цикл? Да, вы можете получить новую куку при запросе, но лучше сохранять их в CookieContainer и дальше работать с ней, а не брать string значение и "парсить" его!
Теперь помогу вам с запросом и покажу, что 80% из запроса попросту можно выкинуть. Зачастую, достаточно 1-2 значений, что бы сайт выдал нам что то. У вас к примеру авторизация - это __RequestVerificationToken
, отправив его, сайт уже не будет "шутить" над вами и говорить, что он чайник, а просто выдаст 500'ю ошибку (неожиданные условия). Давайте поэкспериментируем с запросом:
Content-Type
- данные отправляются в application/x-www-form-urlencoded
.detailNum
- Id деталиgeoCoordsType
- Location
(тип координат)latitude
/longitude
- широта/долгота, координаты выбранного магазина.__RequestVerificationToken
- токен от CSRF атак.__RequestVerificationToken
- аналогично предыдущему.
Как видим, 80% мы попросту можем не слать, серверу не нужен UserAgent
, sessionId
или что то еще, достаточно отправить локацию, id и токен.
В общем удачи и научитесь общаться с такими системами на "ты", они это любят ;-)
Айфон мало держит заряд, разбираемся с проблемой вместе с AppLab
Перевод документов на английский язык: Важность и ключевые аспекты
Такая дилемма: у меня есть эдакий "ItemsSource" в моем элементе управленияDependencyProperty типа IEnumerable
Каким образом сделать, так чтобы оружие моего персонажа дулом было повернуто в сторону моего пальца (тача) и следило за ним, когда вожу по экрану
Подскажите, как привязать в TaskbarIcon метод из MainWindow (а не из отдельного класса команд)Пример от разработчика показывает как привязать из отдельного...
Необходимо изменить/прочитать/добавить переменную Shell в реестре Windows по пути \HKEY_USERS\\Software\Microsoft\Windows NT\CurrentVersion\Winlogon для каждого пользователяОднако...