Я работаю над небольшим проектом по обработке больших данных из игры, который позволит мне просматривать некоторые расширенные аналитические данные. Однако я наткнулся на стену .... Следующий URL (Кликните сюда) - это открытый API, который возвращает результат JSON, и я пытаюсь обработать его как свои собственные данные.
Я создал класс, который должен обрабатывать эти данные в моей модели, однако каждый раз, когда строка 5 называется client.DownloadString, я получаю ошибку 403, есть ли способ обойти это? Не знаю владельца апи.
public IActionResult Index(object sender, EventArgs e)
{
var model = new FresnoVm();
WebClient client = new WebClient();
string strPageCode = client.DownloadString("https://api.upx.world/bigdata/query?neighborhood=210&neighborhood=359&neighborhood=367&neighborhood=366&neighborhood=356&neighborhood=364&city=0&status=All&mintMin=0&mintMax=100000000&saleMin=0&saleMax=100000000&skip=0&fsa=All&sort=mint_price&ascOrDesc=1");
dynamic dobj = JsonConvert.DeserializeObject<dynamic>(strPageCode);
price = dobj["data"]["properties"]["sale_price_upx"].ToString();
model.test = price;
return View("~/Features/Fresno/Index.cshtml", model);
}
Это не связано с ошибкой 403, но если вы получаете JSON размером более 85 000 байт, вам следует десериализовать его непосредственно из потока ответов, а не загружать его как строку и анализировать ее. десериализовать непосредственно из потока ответов, как предложено, например, в newtonsoft.com/json/help/html/Performance.htm#MemoryUsage





Добавьте простую строку, как показано ниже
wb.Headers.Add("User-Agent: Other"); //that is the simple line!
Хотя этого достаточно для загрузки строки, было бы лучше выполнить десериализацию из потока без создания промежуточной строки размером 1,7 МБ, как показано здесь: dotnetfiddle.net/MKkuUi.
Большое спасибо, позвольте мне попробовать это сейчас!
Хотя добавление "User-Agent: Other" в wb.Headers, как предложено в этот ответ от Borg8 до WebClient 403 Запрещено, достаточно для загрузки строки ответа, поскольку возвращаемая строка составляет примерно 1,6 МБ, было бы лучше десериализовать непосредственно из потока ответа, как рекомендовано в Советы по производительности: оптимизация использования памяти Newtonsoft.
Сначала определите следующий вспомогательный метод:
public static class JsonExtensions
{
public static T GetFromJson<T>(string url, JsonSerializerSettings settings = default)
{
var request = (HttpWebRequest)HttpWebRequest.Create(url);
// User-Agent as suggested by this answer https://stackoverflow.com/a/6905471/3744182
// by https://stackoverflow.com/users/873595/borg8
// To https://stackoverflow.com/questions/3272067/webclient-403-forbidden
request.UserAgent = "Other";
using (var response = (HttpWebResponse)request.GetResponse())
{
if (response.StatusCode == HttpStatusCode.OK)
{
using (var stream = response.GetResponseStream())
using (var textReader = new StreamReader(stream))
{
settings = settings ?? new JsonSerializerSettings { CheckAdditionalContent = true };
return (T)JsonSerializer.CreateDefault(settings).Deserialize(textReader, typeof(T));
}
}
else
{
throw new ApplicationException(); // Throw some exception with a message of your choice
}
}
}
}
И тогда вы можете:
var dobj = JsonExtensions.GetFromJson<JToken>(url);
var prices = dobj["data"]["properties"].Select(t => (decimal?)t["last_paid_price_upx"]).ToList(); // Or cast to (string) if you prefer
Заметки:
Что в возвращенном JSON нет свойства с именем "sale_price_upx". Некоторые, но не все, объекты data.properties[*] содержат свойство "last_paid_price_upx", поэтому в приведенном выше коде показан пример того, как извлечь их как десятичные дроби, допускающие значение NULL.
объектная модель документа LINQ-to-JSON может использовать значительные объемы памяти для имен свойств. Вы можете повысить производительность, десериализуя большие объемы данных непосредственно в явную модель данных, содержащую только необходимые вам свойства.
Демо рабочий пример здесь.
Отлично спасибо. Вы знаете, почему нет недвижимости с названием sale_price_upx? это основной, который мне нужен, и когда вы нажимаете на URL-адрес, он отображается в ответе.
@ M.E_ - понятия не имею. Я не знаю конкретно о api.upx.world.
Отвечает ли это на ваш вопрос? WebClient 403 Запрещено