Страницы

Поиск по вопросам

вторник, 16 апреля 2019 г.

Парсинг сайта metanit

Хочу спарсить сайт metanit.com
Стандартными средствами(пример кода https://github.com/extremecodetv/Html-Parser-Tutorial) не выходит. Просто отдает одну пустую страницу.
Пытался использовать Selenium, но тоже работает через раз, да и способ этот мне не нравится: ради парсинга целый движок браузера загружать.
Может вы знаете способ лучше? И почему не работает обычный System.Net.Http.HttpClient ?


Ответ

Проверил я данный сайт. Получаете вы не пустую страницу как таковую, а ошибку 403, которая гласит:
Access forbidden! You don't have permission to access the requested object. It is either read-protected or not readable by the server.
Из за чего это может быть? Хм, ну по сути это происходит по двум причинам:
Вам заблокировали доступ на сервер (или часть сервера) Сервер имеет некую защиту от автоматизации, которая обычно бывает:
Банальная проверка User-Agent заголовка у запроса. Проверка Cookie Комплексные защиты (CloudFlare например, где используют и то и то сразу (а то и больше...)).
Для начала нам стоит отловить запрос, который мы посылаем при заходе на сервер и по очереди добавлять в наш код все, что необходимо.
Лично я всегда использую подобный код для отправки запросов:
public async Task SendRequest(string url) { string data; var baseAddress = new Uri("https://metanit.com"); var cookieContainer = new CookieContainer(); using (var handler = new HttpClientHandler { CookieContainer = cookieContainer }) using (var client = new HttpClient(handler) { BaseAddress = baseAddress }) { var result = await client.GetAsync(url); data = await result.Content.ReadAsStringAsync(); }
return data; }
И так, пробуем по порядку, попробуем задать другой User-Agent. Для этого нам достаточно добавить подобную строку до получения result переменной:
client.DefaultRequestHeaders.Add("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/64.0.3282.140 Safari/537.36 Edge/17.17120");
И о чудо, сервер открыл нам доступ!
Если бы сервер требовал от нас Cookie, то стоило бы добавить что то вроде этого до result
cookieContainer.Add(baseAddress, new Cookie("key", "value"));
В общем, экспериментируйте и смотрите что именно отправляет ваш браузер на сервер, тогда будет в разы легче сделать то, что вы хотите.

Комментариев нет:

Отправить комментарий