Страницы

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

среда, 5 февраля 2020 г.

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

#c_sharp #net #парсер #http


Хочу спарсить сайт metanit.com

Стандартными средствами(пример кода https://github.com/extremecodetv/Html-Parser-Tutorial)
не выходит. Просто отдает одну пустую страницу.

Пытался использовать Selenium, но тоже работает через раз, да и способ этот мне не
нравится: ради парсинга целый движок браузера загружать.

Может вы знаете способ лучше? И почему не работает обычный System.Net.Http.HttpClient ?
    


Ответы

Ответ 1



Проверил я данный сайт. Получаете вы не пустую страницу как таковую, а ошибку 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")); В общем, экспериментируйте и смотрите что именно отправляет ваш браузер на сервер, тогда будет в разы легче сделать то, что вы хотите.

Ответ 2



Приведу пример с HttpWebRequest код получен, парсить можно чем угодно дальше. using System; using System.IO; using System.Net; using System.Text; using System.Windows.Forms; namespace TestParse { public partial class Form1 : Form { public Form1() { InitializeComponent(); } private void button1_Click(object sender, EventArgs e) { txtLog.Text = Parser("https://metanit.com"); } public static string Parser(string url) { HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url); request.Method = "GET"; request.Accept = "application/json"; request.UserAgent = "Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36"; HttpWebResponse response = (HttpWebResponse)request.GetResponse(); StreamReader reader = new StreamReader(response.GetResponseStream()); StringBuilder output = new StringBuilder(); output.Append(reader.ReadToEnd()); response.Close(); return output.ToString(); } } } Раз вы упомянули Selenium приведу пример с использованием WebDriver с возможностью обхода Cloudflare public string GetHtml(string url) { string html = null; try { var driverService = PhantomJSDriverService.CreateDefaultService(); driverService.HideCommandPromptWindow = true; var Driver = new PhantomJSDriver(driverService); Driver.Navigate().GoToUrl(url); while (Driver.PageSource.Contains("setTimeout(function()")) Thread.Sleep(1000); html = Driver.PageSource; Driver.Close(); Driver.Quit(); return html; } catch { } return null; }

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

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