Парсер с использованием Anglesharp.
Как парсить сайты с авторизацией?
Я пробую написать парсер.
Если я правильно понял теорию, то логика должна быть следующая:
- авторизация;
- получить куки;
Движение по страницам
- отправить куки;
- перейти на страницу_1;
- отправить куки;
- перейти на страницу_2;
Форма авторизации
<form name="login" class="ui large form" action="/login/" method="POST">
<div class="required field ui grid aligned left"><input name="login[login]" value="" type="text" placeholder="Электронная почта" maxlength="64" autocomplete="off"></div>
<div class="required field ui grid aligned left">
<input name="login[password]" value="" type="password" maxlength="32" autocomplete="off" placeholder="Пароль">
</div>
<div class="equal width fields" style="flex-wrap:nowrap;">
<div class="field" style="text-align: left;">
<div class="ui checkbox large step">
<input id="remember" type="checkbox" name="login[remember]" tabindex="0" value="1" class="hidden">
<label for="remember">Запомнить меня</label>
</div>
</div>
<div class="field" style="text-align: right;">
<a href="/forgot/">Забыли пароль?</a>
</div>
</div>
<div class="field">
<button class="fluid positive ui button big">Войти</button>
</div>
<input name="login[type]" type="hidden"><input name="login[init]" type="hidden" value="">
</form>
Минимальный код
public async void Authorization(string pathPageLogin, string userName, string password)
{
IConfiguration config = Configuration.Default.WithDefaultLoader().WithCookies();
IBrowsingContext browsingContext = BrowsingContext.New(config);
browsingContext.OpenAsync(pathPageLogin).Wait();
(browsingContext.Active.QuerySelector("input[name = 'login[login]']") as IHtmlInputElement).Value = userName;
(browsingContext.Active.QuerySelector("input[name = 'login[password]']") as IHtmlInputElement).Value = password;
(browsingContext.Active.QuerySelector("form") as IHtmlFormElement).SubmitAsync().Wait();
}
public async void Parsing(string url, string pathFileHtml)
{
HttpClient client = new HttpClient();
var response = await client.GetAsync(url); // скачиваем страницу
string source = await response.Content.ReadAsStringAsync(); // Переносим в переменную
#region Сохранить страницу в файл
File.WriteAllText(pathFileHtml, source);
#endregion Сохранить страницу в файл
#region Парсер
// HTML парсер, который доступен из "AngleSharp".
var domParser = new HtmlParser();
// Спарсим асинхронно наш исходный код и получим документ с которым мы можем работать
var document = await domParser.ParseAsync(source);
// *** Парсер ****
// результат
var list = new List<string>();
var items = document.QuerySelectorAll("a").Where(item =>
item.ClassName != null && item.ClassName.Contains("post__title_link"));
foreach (var item in items)
{
list.Add(item.TextContent);
}
#endregion
}
Вопросы.
1. Правильно ли я понимаю логику?
2. Как сделать код с минимальным набором основных методов для простых сайтов, чтобы было видно принцип логики?
Дополнение
Для примера использовать: rabota.by/login/
Дополнение
Логин - test9631@yandex.by
Пароль - Ym3LDp1FPs
Дополнение
Анализируем.
Первым делом надо проанализировать сайт и понять как он работает. Я лично буду использовать Fiddler для отлова запросов, вы это можете делать там, где вам удобно...
И так, заходим на страницу авторизации, включаем отлов запросов, авторизуемся и смотрим на запросы.
Обычно они выглядят довольно заметно и идут на страницу вида /login
или что то в этом духе.
После авторизации на сайте я поймал такой запрос:
Смотрим сам запрос:
POST /login/ HTTP/1.1
Host: rabota.by
Connection: keep-alive
Content-Length: 186
Cache-Control: max-age=0
Origin: https://rabota.by
Upgrade-Insecure-Requests: 1
DNT: 1
Content-Type: application/x-www-form-urlencoded
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36 Vivaldi/2.2.1388.37
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8
Referer: https://rabota.by/
Accept-Encoding: gzip, deflate, br
Accept-Language: ru-RU,ru;q=0.9,en-US;q=0.8,en;q=0.7
Cookie: sessionRabota=4t8r5v068lb7g9alo3; _ga=GA1.2.20569718.1545649; _gid=GA1.2.202925.15449; _ym_uid=15595112; _ym_d=154552; _ym_isad=1; _ym_visorc_2318=w; 388c2c03bbed9f4661; captcha=4509285; captcha_md5=59bf907333254603af10; arp_scroll_position=0; *0=*0
POST
на адрес /login/
.Content-Type: application/x-www-form-urlencoded
.User-Agent
и некоторые Cookie
.Так, как у нас запрос с данными веб формы, то также стоит посмотреть его тело:
login[login] user@mail.com
login[password] pass
login[remember] 1
submitButton Войти
login[type] cad5afb6ed280bc4041d5689d561144a
Здесь все довольно понятно - наши логин, пароль, запоминать или нет, имя кнопки и неизвестный параметр с логина. Проверим этот неизвестный параметр, просто проделав авторизацию еще раз. Если он изменится, то стоит искать как он формируется, если нет, то можно использовать его. В моем случае он статичный.
Ну и еще стоит посмотреть сам ответ сервера, что он отдает и что он устанавливает:
Content-Type: text/html; charset=UTF-8
Set-Cookie: *0=%2A0; expires=Wed, 12-Dec-2018 19:21:31 GMT; Max-Age=-864000; path=/; domain=rabota.by
Set-Cookie: 666c9aea5601eb92b8=7df1b7318a82be0b068b; expires=Tue, 22-Jan-2019 19:21:32 GMT; Max-Age=2678400; path=/; httponly
Set-Cookie: d2c3f55839194555558=f33b13af8cfcd2d14c8650; expires=Tue, 22-Jan-2019 19:21:32 GMT; Max-Age=2678400; path=/; httponly
Видно, что в ответ сервер отдает нам обычный html и устанавливает пару Cookie. Тело ответа смотреть пока бессмысленно.
Пробуем отправить запрос сами.
Для этих целей отлично подходит Postman. Устанавливаем, пропускаем авторизацию (или нет) и создаем новый запрос.
https://rabota.by/login
x-www-form-urlencoded
Теперь очистим запрос:
*0=*0
.login[login]
, login[password]
и login[type]
.Content-Type
и Referer
.Виртуальный выделенный сервер (VDS) становится отличным выбором
Как сделать чтобы можно было установить шанс выпадения числа в процентах
Пытаюсь разобраться с WPFВ моем примере мне нужно получить доступ к MainWindow viewmodel из Page в XAML
Есть коллекция radiobutton, по нажатии на каждую такую кнопку формируется коллекция togglebuttonДанные для формирования и того и другого списка берутся...