Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Решение Егоров Артём #15

Open
wants to merge 8 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
484 changes: 484 additions & 0 deletions .gitignore

Large diffs are not rendered by default.

56 changes: 56 additions & 0 deletions LinksParser/LinksParser.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
using HtmlAgilityPack;
using System.Text.Json;

namespace LinksParserLib
{
public class LinksParser
{
public async Task<string> ParseLinksAsync(string pathToDocument)
{
if (!File.Exists(pathToDocument))
{
throw new FileNotFoundException("File not found", pathToDocument);
}

string htmlContent = await File.ReadAllTextAsync(pathToDocument);

var htmlDocument = new HtmlDocument();
htmlDocument.LoadHtml(htmlContent);

var listNodes = htmlDocument.DocumentNode.SelectNodes("//a[@href]");
var setDomains = new SelectedSites();

if (listNodes != null)
{
foreach (var linkNode in listNodes)
{
string url = linkNode.GetAttributeValue("href", "");
if (!Uri.TryCreate(url, UriKind.Absolute, out Uri uri))
{
continue;
}

string domain = uri.Host;
if (string.IsNullOrEmpty(domain))
{
continue;
}

domain = TryRemoveWww(domain);

setDomains.Sites.Add(domain);
}
}
return JsonSerializer.Serialize(setDomains);
}
private string TryRemoveWww(string domain)
{
if(domain.Contains("www."))
{
return domain.Replace("www.", "");
}
return domain;
}
}
}

13 changes: 13 additions & 0 deletions LinksParser/LinksParser.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="HtmlAgilityPack" Version="1.11.60" />
</ItemGroup>

</Project>
25 changes: 25 additions & 0 deletions LinksParser/LinksParser.sln
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17
VisualStudioVersion = 17.5.002.0
MinimumVisualStudioVersion = 10.0.40219.1
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LinksParser", "LinksParser.csproj", "{BBAF44A1-14C1-4203-B6CA-B6E885505726}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{BBAF44A1-14C1-4203-B6CA-B6E885505726}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{BBAF44A1-14C1-4203-B6CA-B6E885505726}.Debug|Any CPU.Build.0 = Debug|Any CPU
{BBAF44A1-14C1-4203-B6CA-B6E885505726}.Release|Any CPU.ActiveCfg = Release|Any CPU
{BBAF44A1-14C1-4203-B6CA-B6E885505726}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {6CEA9F53-5407-4B32-A82A-63FC4E25A5B8}
EndGlobalSection
EndGlobal
14 changes: 14 additions & 0 deletions LinksParser/SelectedSites.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
using System.Text.Json.Serialization;

namespace LinksParserLib
{
public class SelectedSites
{
[JsonPropertyName("sites")]
public SortedSet<string> Sites { get; set; }
public SelectedSites()
{
Sites = new SortedSet<string>();
}
}
}
19 changes: 18 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,24 @@
4. Найденные в соответствии с условием задачи домены должны выводиться в нижнем регистре без указания протокола и «www» в алфавитном порядке.

## Автор решения

Егоров Артём Олегович
## Описание реализации
Идея решения - парсить html-документ (`HtmlDocument htmlDocument`) для поления списка всех тэгов `a`, которые имеют атрибут `href`. Проанализировать каждый элемент списка (`HtmlNodeCollection listNodes`) на налачие доменного имени. Если таковое имеется, то добавляем доменное имя в множество уникальных элементов (`SelectedSites setDomains`). Для сохранения результата работы функции используется отдельный класс `SelectedSites`, имеющий в себе свойство `SortedSet Sites` (`SortedSet` используется для хранения доменов в лексикографическом порядке)

Подробнее:
1. Метод ParseLinksAsync принимает путь к HTML-документу, загружает его, а затем асинхронно разбирает содержимое, извлекая все ссылки `<a>` с атрибутом `href`.
2. Для каждой ссылки извлекается домен, и если он не пустой, преобразуется в URI и проверяется на наличие префикса "www.".
3. Уникальные домены добавляются в объект `SelectedSites`, а затем сериализуются в формат JSON.

### Про библиотеку HtmlAgilityPack

[HtmlAgilityPack](https://github.com/zzzprojects/html-agility-pack) - библиотека для парсинга html-документов с открым исходным кодом. Разрабатывается под лицензией MIT, которая не восприщает использование её в коммерческих продуктах.

[Подробнее про MIT](https://mit-license.org/)
## Инструкция по сборке и запуску решения
1. Сборка решения LinksParses:
1. Переходим в директорию LinksParser
2. Выполняет в терминале `dotnet build`
2. Тестирование решения:
1. Переходим в директорию Test
2. Выполняем в терминале `dotnet test`
13 changes: 13 additions & 0 deletions Resource/domain_and_another_shemas.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>HTML Page with Links to Different Protocols</title>
</head>
<body>
<a href="https://example.com">Link to HTTPS</a>
<a href="http://example.com">Link to HTTP</a>
<a href="ftp://example.com">Link to FTP</a>
</body>
</html>
12 changes: 12 additions & 0 deletions Resource/domain_and_subdomain.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>HTML Page with Links to Domain and Subdomain</title>
</head>
<body>
<a href="https://www.example.com">Link to Main Domain</a>
<a href="https://subdomain.example.com">Link to Subdomain</a>
</body>
</html>
12 changes: 12 additions & 0 deletions Resource/domain_and_wwwdomain.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>HTML Page with Links to Domain and www Subdomain</title>
</head>
<body>
<a href="https://example.com">Link to Main Domain</a>
<a href="https://www.example.com">Link to www Subdomain</a>
</body>
</html>
Loading