Tutoriel
Récupérer les données Open Graph à partir d’une URL en C# et .NET Core
Les métadonnées OpenGraph sont des données qui permettent (notamment) de créer une prévisualisation pour un lien lorsqu’on le partage sur Internet.
Plus d’infos dans notre article dédié à OpenGraph : https://code-garage.fr/blog/comment-personnaliser-le-partage-de-votre-site-sur-les-reseaux-sociaux-avec-opengraph
Si vous gérer des liens dans votre logiciel, vous avez sûrement envie de pouvoir faire une prévisualisation comme ceci :
Etape 1 : Préparer le projet
Pour mener le projet à bien, vous allez avoir besoin de deux modules :
using System.Web; //Utilisé pour charger la page
using HtmlAgilityPack; //Utilisé pour parser la page
Pour
HtmlAgilityPack
vous devrez l’installer via votre gestionnaire de paquets NuGet
Ensuite on va préparer un modèle de données simple pour accueillir nos métadonnées Open Graph, comme ceci :
public record LinkPreview
{
public int? Id { get; set; }
public string Url { get; init; } = String.Empty;
public string Title { get; init; } = String.Empty;
public string Description { get; init; } = String.Empty;
public string ImageUrl { get; init; } = String.Empty;
public string SiteName { get; init; } = String.Empty;
public DateTime LastUpdate { get; init; }
}
Puis on va déclarer notre classe OpenGraphLoader
et sa fonction principale qui prendra une url en entrée et retournera (s’il existe), une instance de LinkPreview
:
public class OpenGraphLoader
{
readonly HttpClient _client;
public OpenGraphLoader ()
{
// Initialisation de notre client HTTP
_client = new HttpClient();
}
public async Task<LinkPreview?> GetLinkPreview(string url)
{
return null;
}
}
Notre classe va contenir une instance d’un client HTTP pour pouvoir faire la requête faire la page web.
Pour l’instant, la fonction principale est vide, et nous allons maintenant écrire la logique ce celle-ci !
Etape 2 : Charger la page web
Pour charger le contenu HTML de notre page web, il va falloir utiliser le client HTTP préalablement initialisé, et lui passer notre URL.
Le contenu de la réponse est simplement une suite d’octets, il va donc falloir re-transformer ces octets en String
pour retrouver notre code HTML :
public async Task<LinkPreview?> GetLinkPreview(string url)
{
// Exécute la requête vers l'url de la page web
var response = await _client.GetAsync(url);
// Parse le corps de la réponse (la page) en string
var html = await response.Content.ReadAsStringAsync();
/*
Ici nous allons parser
nos métadonnées
*/
return null;
}
Il ne nous reste plus qu’à utiliser fouiller dans ce code HTML à la recherche de nos métadonnées et de leurs valeurs
Etape 3 : Parser les métadonnées
Pour cette étape nous allons utiliser le paquet HtmlAgilityPack
qui va nous permettre de charger le code HTML pour le transformer en un vrai document HTML que nous allons pouvoir parcourir :
// Charge le contenu HTML dans un HtmlDocument
var doc = new HtmlDocument();
doc.LoadHtml(html);
Puis on va pouvoir sélectionner les éléments HTML qui nous intéressent (les fameuses balises OpenGraph), et récupérer leurs valeurs une à une :
// Sélectionne tous les éléments <meta> avec l'attribut property="og:*"
var metaTags = doc.DocumentNode.SelectNodes("//meta[starts-with(@property, 'og:')]");
// Créer un dictionnaire pour stocker tous les noms des éléments et leur valeur
var openGraphData = new Dictionary<string, string>();
// Extrait les données et les ajoute au dictionnaire une par une
if (metaTags != null)
{
foreach (var tag in metaTags)
{
var property = tag.GetAttributeValue("property", "");
var content = tag.GetAttributeValue("content", "");
if (!string.IsNullOrEmpty(property) && !string.IsNullOrEmpty(content))
{
// Supprime le prfixe 'og:' du nom de la propriété
property = property.Replace("og:", "");
openGraphData[property] = content;
}
}
} else {
return null;
}
Dans le cas où aucune balise
og:*
n’est trouvée, la fonction retourneranull
, mais vous pouvez décider de renvoyer unLinkPreview
vide à la place !
Et enfin, il ne reste plus qu’à passer toutes ces données à notre objet LinkPreview
(si des métadonnées ont été trouvées) et à le retourner à la fin de notre fonction :
return new LinkPreview()
{
Url = url,
Title = openGraphData["title"],
Description = openGraphData["description"],
ImageUrl = openGraphData["image"],
SiteName = openGraphData["site_name"],
LastUpdate = DateTime.Now
};
Et voilà ! Vous pouvez désormais récupérer les balises Open Graph de n’importe quelle page web (à condition qu’elles existent) !
Et vous pouvez bien évidemment adapter ce code pour récupérer d’autres informations présentes sur la page.
Le code complet
Voici l’entièreté du code de ce tutoriel, avec tous les commentaires :
using System.Web; //Utilisé pour charger la page
using HtmlAgilityPack; //Utilisé pour parser la page
namespace App;
public record LinkPreview
{
public int? Id { get; set; }
public string Url { get; init; } = String.Empty;
public string Title { get; init; } = String.Empty;
public string Description { get; init; } = String.Empty;
public string ImageUrl { get; init; } = String.Empty;
public string SiteName { get; init; } = String.Empty;
public DateTime LastUpdate { get; init; }
}
public class OpenGraphLoader
{
readonly HttpClient _client;
public OpenGraphLoader ()
{
// Initialisation de notre client HTTP
_client = new HttpClient();
}
public async Task<LinkPreview?> GetLinkPreview(string url)
{
// Exécute la requête vers l'url de la page web
var response = await _client.GetAsync(url);
// Parse le corps de la réponse (la page) en string
var html = await response.Content.ReadAsStringAsync();
// Charge le contenu HTML dans un HtmlDocument
var doc = new HtmlDocument();
doc.LoadHtml(html);
// Select all meta tags with property attribute starting with 'og:'
var metaTags = doc.DocumentNode.SelectNodes("//meta[starts-with(@property, 'og:')]");
// Create a dictionary to store OpenGraph metadata
var openGraphData = new Dictionary<string, string>();
// Extract content from meta tags and add it to the dictionary
if (metaTags != null)
{
foreach (var tag in metaTags)
{
var property = tag.GetAttributeValue("property", "");
var content = tag.GetAttributeValue("content", "");
if (!string.IsNullOrEmpty(property) && !string.IsNullOrEmpty(content))
{
// Remove 'og:' prefix from property
property = property.Replace("og:", "");
openGraphData[property] = content;
}
}
} else {
return null;
}
return new LinkPreview()
{
Url = url,
Title = openGraphData["title"],
Description = openGraphData["description"],
ImageUrl = openGraphData["image"],
SiteName = openGraphData["site_name"],
LastUpdate = DateTime.Now
};
}
}
Vous pouvez directement copier-coller ce code, mais si vous ne comprenez pas certaines parties, pensez à relire l’entièreté du tutoriel !
Avant de terminer
Chaque url que vous allez prévisualiser pourra prendre plus ou moins de temps à se charger, cela peut donc ralentir votre logiciel.
Vous pouvez évidemment rendre ce traitement non-bloquant, mais ce n’est pas toujours possible selon votre cas d’usage !
L’idéal est de stocker le résultat de ces appels dans une base de donnée (avec comme identifiant l’url), pour créer un cache temporaire, et minimiser le nombre de requêtes (et donc le temps d’exécution) des appels à cette fonction !
Pour lire la suite de ce tutoriel, vous devez posséder un compte gratuit