0

Ссылка - https://www.ambellahome.com/Product/Detail/811-00/Brittany-Arm-Chair

Генерирую куку, но она не проходит

 string likn = WebUtility.UrlDecode(cait.QuerySelector("a").GetAttribute("href"));
                    string ost = likn.Substring(likn.IndexOf("Product/")).Replace("Product/", "");
                    string catrgory = ost.Substring(0, ost.IndexOf("/"));
                    string id = ost.Substring(ost.LastIndexOf("/") + 1);
                    string cookie_value = "\"id\":\"" + id + "\"," + "\"category\":\"" + catrgory + "\",\"type\":\"Category\",\"referer\":\"" + "https://www.ambellahome.com" + cait.QuerySelector("a").GetAttribute("href") + "\",\"queryString\":\"\"";
                    Console.WriteLine(cookie_value);
                    try
                    {
                        Program.cookieContainer.Add(Program.baseAddress, new Cookie("SEARCH_QUERY",  cookie_value));
                }
                catch(Exception e)
                {

                }

Pola Goun
  • 3
  • 2
  • Ерундой вы какой-то занимаетесь, ибо во-первых, у вас в cookie_value в итоге белеберда, а не JSON (который просит сервер), во вторых, вы делаете уйму лишнего, ибо JSON он и в африке JSON и с ним надо работать при помощи нужных инструментов, ну и в-третьих, зачем вам вообще делать это все самостоятельно? Зашли на адрес любого поиска, оно вам нагерерировало куку, все, пользуйтесь сайтом дальше, как вам надо. – EvgeniyZ Dec 07 '20 at 19:03
  • @EvgeniyZ так он сам её где-то генерит, и мне не отдает. А про инструменты не знаю, поэтому так и сделал, можете помочь с этим всем? – Pola Goun Dec 07 '20 at 19:15
  • https://ru.stackoverflow.com/q/1178026/373567 вот так можно вообще забыть про куки, их можно сохранить или загрузить. HttpClient по умолчанию их принимает, хранит и отправляет серверу как того требуют стандарты. Я просто к этому прикрутил их загрузку и сохранение. И не надо вручную творить баги. – aepot Dec 07 '20 at 19:45
  • @aepot, классная функция, но есть одно но, я уже формирую json, и тут выдает мне ошибку '{"The 'Value'='{"id":"Arm & Side Chairs","category":"Dining & Serving","type":"Category","referer":"https://www.ambellahome.com/Product/Dining%20%26%20Serving/Arm%20%26%20Side%20Chairs","queryString":""}' part of the cookie is invalid."}' – Pola Goun Dec 07 '20 at 19:52
  • @aepot мне теперь тупо осталось формировать json, который куки отказывается принимать – Pola Goun Dec 07 '20 at 19:53
  • Я сразу не въехал, что запрос через куку улетает, супермегаприкольно. Тогда вам мой метод не очень подходит, потому что задача другая. Уж простите, с ходу не разобрался, а @EvgeniyZ совершенно верно все ниже изложил. Точнее через DefaultRequestHeader получится, но в остальном функционале у вас нет нужды. Мой метод больше подходит, когда надо эмулировать поведение браузера по кукам при обращении к серверу, например авторизоваться и использовать сайт под какой-нибудь учетной записью. Либо доработать так, чтобы в контейнер залетала кука при запросе, но опять же она вам в контейнере не нужна. – aepot Dec 07 '20 at 20:27

1 Answers1

2

Вся ваша проблема в том, что в указанном вами коде попросту нету валидного JSON, ибо как минимум он должен начинаться с { и заканчиваться на }, а у вас простой набор символов. Перестаньте писать JSON руками, будьте ленивым программистом, за которого сделает все система!

За JSON в C# отвечают либо сторонние библиотеки (из популярных Newtonsoft.JSON), либо не так давно вышедшая System.Text.Json. Собственно, что тут выбирать я оставлю на вас, а чисто в этом примере качать лишнее бес толку.

Сначала давайте определимся что нам именно надо отправить, а для этого берем Postman и собираем в нем успешный запрос на сервер, добавив в него необходимые заголовки и Cookie. Как только мы это сделаем, получим такое:

postman_cookie

Как видим, нам достаточно лишь отправить id и тип, а не всю портянку. Теперь значит мы можем сделать либо класс, либо что-то что будет лишь содержать в себе данные, тут отлично подойдут анонимные типы!

var data = new { id = "123", type = "Search" };
var json = JsonSerializer.Serialize(data);

И смотрите, всего 2 строки (а можно и в одну) и мы переписали полностью всю вашу белеберду и сделали код проще и удобней. Остается лишь отправить это все.

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

var data = new { id = "123", type = "Search" };
client.DefaultRequestHeaders.Add("Cookie", $"SEARCH_QUERY={JsonSerializer.Serialize(data)}");

Только не забудьте задать BaseAddress клиенту...

Пример онлайн

EvgeniyZ
  • 15,694
  • Cпасибо, очень выручили. Я одного не могу понять, почему мы добавляем в заголовок, а не в куки контейнер? – Pola Goun Dec 07 '20 at 20:16
  • @PolaGoun Ну для начала - смысл? Вам ведь не нужна будет на этом сайте авторизация или что либо еще, ведь так? Если это проект, где надо лишь найти нужный товар, обработать данные и выдать их, то смысл тянуть контейнер и все остальное (это еще будет несколько строк кода)? Ну и к тому же, в простую Cookie просто так JSON не засунуть (это я думаю вы уже поняли, судя по вашим комментариям). В любом случае, моя цель была показать вам как убрать тот ужас и выдать грамотный JSON, а как это занести в Cookie, дело десятое) – EvgeniyZ Dec 07 '20 at 20:20
  • да уже понял, просто первый раз с таким столкнулся. А есть статья мб какая-нибудь, для общего развития. В чем разница куки контейнера, и куки в заголовках? – Pola Goun Dec 07 '20 at 20:23
  • 1
    @PolaGoun Есть Cookie - некий объект, который хранит в себе ключ и значение, а также он имеет свой срок и параметры как домен и путь. Контейнер - место, где все эти "печаньки" хранятся. А заголовки - туда автоматически подставляются нужные Cookie из контейнера при запросе. То есть, при запросе куда либо, если в контейнере есть печенька с нужным доментом, то она автоматически подставиться в заголовок, а если сервер вдруг даст новую печеньку, то она автоматически будет записана в этот контейнер. Мы же с вами эту автоматизацию убрали и взяли на себя роль контейнера. – EvgeniyZ Dec 07 '20 at 20:30
  • @PolaGoun в том, что контейнер работает с тем что HttpClient принимает и отправляет автоматически. Прилетает ответ от сервера с заголовком Set-Cookie, кука автоматом попадает в контейнер. При следующем запросе на этот же сервер, HttpClient ее автоматически достанет и отправит серверу назад, так и работает авторизация в браузере, ну и в HttpClient тоже. А кука в заголовке - это то что вы просто добавили в запрос, и всё. Она может быть добавлена дополнительно к кукам из контейнера. – aepot Dec 07 '20 at 20:31
  • Спасибо, всем за помощь – Pola Goun Dec 07 '20 at 20:49