-1

Имею необходимость научиться пасрить сайт без API (на самом деле API я находил, но на питоне). С# я начал изучать около 2 недель назад, так что я еще практически ничего не знаю. Я планирую что моя программа будет уметь вытаскивать определенный текст с конкретной страницы которую я укажу, помещать конкретный текст в конкретные тексБоксы, на тот случай если текст нужно подкорректировать, и затем "собирать" весь текст из разных текстБоксов в одну "многострочную строчку". Не спрашивайте зачем.

И... В общем то почти все из запланированного я сделал. Не до конца но наполовину. Я скачиваю весь сайт, регулярными выражениями вытягиваю текст, и делаю все остальные грязные дела. Но везде, во всех уроках, комментариях и советах пишут, что нельзя для этого использовать регулярные выражения, и нельзя качать весь сайт. Или API, или AngleSharp советуют. Но по AngleSharp ничего адекватного не удается найти. Или какие то абстракции, только теория, или практика на узких примерах, не подходящих мне.

И вот я забрел сюда, на это сообщение. Там много чего написано, наверняка полезного, но мне не помогло.

Во допустим у меня такой код.

async Task DownloadStringAsync()
{
    WebClient source = new WebClient();
    string reply = source.DownloadString(@"какая-то_страница");
    Match match1 = Regex.Match(reply, "<h1 itemprop=\"name\" id=\"work_name\">(.*?)</h1>");
EngNameTextBox.Text = match1.Groups[1].Value;

}

Он парсит нужный мне текст

<h1 itemprop="name" id="work_name">Нужный мне текст</h1>

Как мне тоже самое сделать с помощью AngleSharp? С нуля, у меня только открытый проект и подключенный AngleSharp (через консоль диспетчера пакетов подключал). h1 - это получается тег? Так вроде в уроке писали. А itemprop и work_name атрибуты вроде? И как это использовать теперь? В документации я встречал такой код

async Task DownloadStringAsync()
{
    WebClient url = new WebClient();
    string source = url.DownloadString(@"какая-то_страница");
    IConfiguration config = Configuration.Default;
    IBrowsingContext context = BrowsingContext.New(config);
    IDocument document = await context.OpenAsync(req => req.Content(source));
    textBox2.Text = document.DocumentElement.OuterHtml;
}

Но что то мне подсказывает что это совсем не то. В шапке прошлой темы похожий пример. Сработает если я просто его скопирую?

void DownloadString()
{
    var parser = new HtmlParser();
    var doc = parser.ParseDocument(@"https://какая-то_страница.html");
    var seller = doc.QuerySelector("[itemprop='seller']");
    var name = seller.QuerySelector("[itemprop='name']").Text();
    textBox2.Text = name;
}

Не сработало, ошибка на строчке var seller = doc.QuerySelector("[itemprop='seller']");

Иной код

var parser = new HtmlParser();
var doc = parser.ParseDocument(@"какая-то_страница");
string name = doc.QuerySelector("h1").Text();
EngGameNameTextBox.Text = name;

Тоже ошибка. Ошибка именно при выполнении кода. Сама студия никаких ошибок не видит.

Заметил наконец ошибку, должно быть не parser.ParseDocument, а просто parser.Parse

Но тогда студия ругается что Html.Parser не содержит определение Parse.

Помимо того что я уже указал, у меня еще и такие регулярные выражения в наличии.

Match match2 = Regex.Match(reply, "<a href=\"https://www.какой-то_сайт.com/profile/=/maker_id/[0-9]*.html\">(.*?)</a>");
Match match3 = Regex.Match(reply, "<td><a href=\"https://www.какой-то_сайт.com/new/=/year/[0-9]*/mon/[0-9]*/day/[0-9]*/cyear/[0-9]*/cmon/[0-9]*\">(.*?)</a></td>");
MatchCollection match6 = Regex.Matches(reply, "<a href=\"https://www.какой-то_сайт.com/genre/[0-9][0-9][0-9]/from/work.genre\">(.*?)</a>");
for (int i = 0; i < match6.Count; i++)
        {
            if (GenreTextBox2.Text == "")
                GenreTextBox2.Text = match6[i].Groups[1].Value;
            else
                GenreTextBox2.Text = GenreTextBox2.Text + ", " + match6[i].Groups[1].Value;
        }
<a href="https://www.какой-то_сайт.com/profile/=/maker_id/23822.html">Нужный текст 2</a>
<td><a href="https://www.какой-то_сайт.com/new/=/year/2022/mon/02/day/20/cyear/2022/cmon/02">Нужный текст 3</a></td>  </tr>
<a href="https://www.какой-то_сайт.com/genre/068/from/work.genre">Нужный текст 4</a>
<a href="https://www.какой-то_сайт.com/genre/233/from/work.genre">Нужный текст 5</a>
<a href="https://www.какой-то_сайт.com/genre/134/from/work.genre">Нужный текст 6</a>
<a href="https://www.какой-то_сайт.com/genre/142/from/work.genre">Нужный текст 7</a>
<a href="https://www.какой-то_сайт.com/genre/182/from/work.genre">Нужный текст 8</a>

Как должны выглядеть аналоги такого же кода с AngleSharp?

Или лучше оставить все как есть?

K14M
  • 19
  • 2
  • Много воды. 2. Спалили ссылку. 3. начал изучать около 2 недель назад - без опыта, в парсинг, не лучшая идея, очень много подводных камней. 4.Что не понятного в том ответе, что вы привели? Ну вот возьмем ваш HTML <h1 itemprop="name" id="work_name">Нужный мне текст</h1>, мы хотим его забрать, пишем значит h1, то есть мы забираем первый попавшийся h1 на сайте. Далее конкретизируем, например нам нужен тот, у кого id="work_name", значит пишем h1#work_name. Если не важен тег, то можем просто #work_name. Остальное все по аналогии, точка - класс, решетка - id, кв. скобки - тег.
  • – EvgeniyZ Jan 02 '23 at 22:04
  • 2
    Теперь про ваши примеры. Пример с DownloadStringAsync() - тут вы просто получаете HTML, без какого либо получения объектов. Пример с DownloadString() - метод ParseDocument() ожидает от вас строку, либо Stream, то есть, он от вас ждет сразу HTML, а вы ему ссылку, естественно он не может дальше найти нужные элементы. Также в этом примере у вас используется устаревший в C# класс WebClient, не стоит его использовать. – EvgeniyZ Jan 02 '23 at 22:08