Comment extraire des données de LinkedIn : guide 2025

Apprenez à créer un scraper LinkedIn basé sur Python, à contourner les murs de connexion et à extraire des données clés sur les emplois pour obtenir de meilleures informations.
26 min de lecture
How to scrape LinkedIn

Dans ce guide, vous apprendrez :

  • Qu’est-ce qu’un scraper LinkedIn?
  • Une comparaison entre le scraping web de LinkedIn et la récupération de données via ses API
  • Comment contourner le mur de connexion LinkedIn
  • Comment créer un script de scraping LinkedIn en Python
  • Comment obtenir des données LinkedIn avec une solution plus simple et plus efficace

C’est parti !

Qu’est-ce qu’un scraper LinkedIn ?

Un scraper LinkedIn est un outil qui extrait automatiquement les données des pages LinkedIn. Il cible généralement les pages populaires telles que les profils, les offres d’emploi, les pages d’entreprise et les articles.

Le scraper collecte les informations clés de ces pages et les présente dans des formats utiles tels que CSV ou JSON. Ces données sont précieuses pour la génération de prospects, la recherche d’emploi, l’analyse des concurrents et l’identification des tendances du marché, entre autres cas d’utilisation.

Scraping web LinkedIn vs API LinkedIn

LinkedIn fournit une API officielle qui permet aux développeurs de s’intégrer à la plateforme et de récupérer certaines données. Alors, pourquoi devriez-vous envisager le Scraping web LinkedIn ? La réponse est simple et comporte quatre points clés :

  1. L’API ne renvoie qu’un sous-ensemble de données défini par LinkedIn, qui peut être beaucoup plus petit que les données disponibles via le Scraping web.
  2. Les API peuvent évoluer au fil du temps, ce qui limite le contrôle que vous avez sur les données auxquelles vous pouvez accéder.
  3. L’API de LinkedIn est principalement axée sur les intégrations marketing et commerciales, en particulier pour les utilisateurs de la version gratuite.
  4. L’API LinkedIn peut coûter plusieurs dizaines de dollars par mois, mais elle impose toujours des restrictions strictes sur les données et le nombre de profils à partir desquels vous pouvez récupérer des données.

La comparaison entre les deux approches pour obtenir des données LinkedIn donne lieu au tableau récapitulatif suivant :

Aspect API LinkedIn Scraping web LinkedIn
Disponibilité des données Limitée à un sous-ensemble de données défini par LinkedIn Accès à toutes les données accessibles au public sur le site
Contrôle des données LinkedIn contrôle les données fournies Contrôle total sur les données que vous récupérez
Objectif Principalement pour les intégrations marketing et commerciales Peut cibler n’importe quelle page LinkedIn
Coût Peut coûter plusieurs dizaines de dollars par mois Aucun coût direct (à l’exception de l’infrastructure)
Limitations Nombre limité de profils et de données par mois Aucune limitation stricte

Pour plus d’informations, consultez notre guide sur le scraping web et les API.

Quelles données extraire de LinkedIn ?

Voici une liste partielle des types de données que vous pouvez extraire de LinkedIn :

  • Profil: informations personnelles, expérience professionnelle, formation, relations, etc.
  • Entreprises: informations sur l’entreprise, listes d’employés, offres d’emploi, etc.
  • Offres d’emploi: descriptions de poste, candidatures, critères, etc.
  • Postes à pourvoir: intitulé du poste, entreprise, lieu, salaire, etc.
  • Articles: publications, articles rédigés par les utilisateurs, etc.
  • LinkedIn Learning: cours, certifications, parcours d’apprentissage, etc.

Comment contourner le mur de connexion LinkedIn

Si vous essayez d’accéder directement à la page LinkedIn Jobs après une recherche Google en mode incognito (ou lorsque vous êtes déconnecté), voici ce que vous devriez obtenir :

The LinkedIn login wall

La page ci-dessus peut vous laisser penser que la recherche d’emploi sur LinkedIn n’est possible qu’après connexion. Étant donné que le scraping de données derrière un mur de connexion peut entraîner des problèmes juridiques car il peut enfreindre les conditions d’utilisation de LinkedIn, il vaut mieux l’éviter.

Heureusement, il existe une solution simple pour accéder à la page Emplois sans être bloqué. Il vous suffit de vous rendre sur la page d’accueil de LinkedIn et de cliquer sur l’onglet « Emplois » :

Clicking on the “Jobs” link on LinkedIn’s homepage

Cette fois-ci, vous aurez accès à la page de recherche d’emploi :

The unblocked job search page

Comme vous pouvez le voir dans la barre d’adresse de votre navigateur, l’URL contient cette fois-ci des paramètres de requête spéciaux :

https://www.linkedin.com/jobs/search?trk=guest_homepage-basic_guest_nav_menu_jobs&position=1&pageNum=0

En particulier, l’argument trk=guest_homepage-basic_guest_nav_menu_jobs semble être le facteur clé qui empêche LinkedIn d’imposer un mur de connexion.

Cependant, cela ne signifie pas que vous pouvez accéder à toutes les données LinkedIn. Certaines sections nécessitent toujours que vous soyez connecté. Pourtant, comme nous allons le voir, cela ne constitue pas une limitation majeure pour le Scraping web LinkedIn.

Créer un script de Scraping web LinkedIn : guide étape par étape

Dans cette section du tutoriel, vous apprendrez à extraire les données des offres d’emploi pour les postes d’ingénieur logiciel à New York sur LinkedIn:

Software engineer positions in NY

Nous commencerons par la page de résultats de recherche, récupérerons automatiquement les URL des offres d’emploi, puis extrairons les données de leurs pages détaillées. Le scraper LinkedIn sera écrit en Python, l’un des meilleurs langages de programmation pour le Scraping web.

Réalisons le scraping des données LinkedIn avec Python !

Étape n° 1 : configuration du projet

Avant de commencer, assurez-vous que Python 3 est installé sur votre ordinateur. Sinon, téléchargez-le et suivez l’assistant d’installation.

À présent, utilisez la commande ci-dessous pour créer un dossier pour votre projet de scraping :

mkdir linkedin-scraper

linkedin-scraper représente le dossier de projet de votre scraper LinkedIn Python.

Entrez-y et initialisez un environnement virtuel à l’intérieur :

cd linkedin-scraper
python -m venv venv

Chargez le dossier du projet dans votre IDE Python préféré. Visual Studio Code avec l’extension Python ou PyCharm Community Edition feront l’affaire.

Créez un fichier scraper.py dans le dossier du projet, qui doit contenir cette structure de fichiers :

The file structure of the LinkedIn Scraper

Pour l’instant, scraper.py est un script Python vide, mais il contiendra bientôt la logique de scraping souhaitée.

Dans le terminal de l’IDE, activez l’environnement virtuel. Sous Linux ou macOS, lancez cette commande :

./env/bin/activate

De manière équivalente, sous Windows, exécutez :

env/Scripts/activate

Parfait ! Vous disposez désormais d’un environnement Python pour le Scraping web.

Étape n° 2 : sélection et installation des bibliothèques de scraping

Avant de vous lancer dans le codage, vous devez analyser le site cible afin de déterminer les outils de scraping adaptés à la tâche.

Commencez par ouvrir la page de recherche d’emplois LinkedIn en mode navigation privée, comme expliqué précédemment. Le mode navigation privée garantit que vous êtes déconnecté et qu’aucune donnée mise en cache n’interfère avec le processus de scraping.

Voici ce que vous devriez voir :

Note the two popups on the target page

LinkedIn affiche plusieurs fenêtres contextuelles dans le navigateur. Celles-ci peuvent être gênantes lorsque vous utilisez des outils d’automatisation de navigateur tels que Selenium ou Playwright.

Heureusement, si vous inspectez le code source HTML de la page renvoyée par le serveur, vous verrez qu’il contient déjà la plupart des données de la page :

The HTML source code of the target page

De même, si vous consultez l’onglet « Réseau » dans DevTools, vous remarquerez que la page ne repose pas sur des appels d’API dynamiques importants :

The AJAX calls performed by the page

En d’autres termes, la plupart du contenu des pages d’emploi LinkedIn est statique. Cela signifie que vous n’avez pas besoin d’un outil d’automatisation du navigateur pour extraire les données de LinkedIn. Une combinaison d’un client HTTP et d’un analyseur HTML suffira pour récupérer les données d’emploi.

Nous utiliserons donc deux bibliothèques Python pour extraire les offres d’emploi de LinkedIn :

  • Requests: une bibliothèque HTTP simple pour envoyer des requêtes GET et récupérer le contenu des pages web.
  • Beautiful Soup: un analyseur HTML puissant qui facilite l’extraction de données à partir de pages web.

Dans un environnement virtuel activé, installez les deux bibliothèques à l’aide de la commande suivante :

pip install requests beautifulsoup4

Ensuite, importez-les dans scraper.py à l’aide de la commande suivante :

from bs4 import BeautifulSoup
import requests

Parfait ! Vous disposez désormais de tout ce dont vous avez besoin pour commencer à scraper LinkedIn.

Étape n° 3 : structurer le script de scraping

Comme expliqué dans l’introduction de cette section, le scraper LinkedIn effectuera deux tâches principales :

  1. Récupérer les URL des pages d’emploi à partir de la page de recherche d’emploi LinkedIn
  2. Extraire les détails de chaque offre d’emploi spécifique

Pour que le script reste bien organisé, structurez votre fichier scraper.py avec deux fonctions :

def retrieve_job_urls(job_search_url):
    pass
    # À implémenter...

def scrape_job(job_url):
    pass
    # À implémenter...

# Appels de fonction et logique d'exportation des données...

Voici ce que font les deux fonctions :

  • retrieve_job_urls(job_search_url): Accepte l’URL de la page de recherche d’emploi et renvoie une liste d’URL de pages d’emploi.
  • scrape_job(job_url): Accepte l’URL d’une page d’emploi et extrait les détails de l’emploi tels que le titre, l’entreprise, le lieu et la description.

Ensuite, à la fin du script, appelez ces fonctions et implémentez la logique d’exportation des données pour stocker les données d’emploi récupérées. Il est temps d’implémenter cette logique !

Étape n° 4 : se connecter à la page de recherche d’emploi

Dans la fonction retrieve_job_urls(), utilisez la bibliothèque requests pour récupérer la page cible à l’aide de l’URL passée en argument :

response = requests.get(job_url)

En arrière-plan, cela effectue une requête HTTP GET vers la page cible et récupère le document HTML renvoyé par le serveur.

Pour accéder au contenu HTML de la réponse, utilisez l’attribut .text:

html = response.text

Incroyable ! Vous êtes maintenant prêt à analyser le HTML et à commencer à extraire les URL des offres d’emploi.

Étape n° 5 : récupérer les URL des offres d’emploi

Pour analyser le code HTML récupéré précédemment, transmettez-le au constructeur Beautiful Soup :

soup = BeautifulSoup(html, "html.parser")

Le deuxième argument spécifie l’analyseur HTML à utiliser. html.parser est l’analyseur par défaut inclus dans la bibliothèque standard de Python.

Ensuite, inspectez les éléments de la fiche d’emploi sur la page de recherche d’emploi LinkedIn. Cliquez avec le bouton droit de la souris sur l’un d’entre eux et sélectionnez « Inspecter » dans les outils de développement de votre navigateur :

Inspecting a job card

Comme vous pouvez le voir dans le code HTML de la fiche d’emploi, les URL des offres d’emploi peuvent être extraites à l’aide du sélecteur CSS suivant :

[data-tracking-control-name="public_jobs_jserp-result_search-card"]

Remarque: l’utilisation des attributs data-* pour la sélection de nœuds dans le Scraping web est idéale, car ceux-ci sont souvent utilisés pour des tests ou un suivi interne. Ils sont donc moins susceptibles de changer au fil du temps.

Maintenant, si vous jetez un œil à la page, vous verrez que certaines fiches d’emploi peuvent apparaître floues derrière un élément d’invitation à se connecter :

The blurred job cards have the same HTML structure as the non-blurred ones

Ne vous inquiétez pas, il s’agit simplement d’un effet frontal. Le code HTML sous-jacent contient toujours les URL des pages d’emploi, vous pouvez donc obtenir ces URL sans vous connecter.

Voici la logique permettant d’extraire les URL des offres d’emploi de la page LinkedIn Jobs :

job_urls = []

job_url_elements = soup.select("[data-tracking-control-name="public_jobs_jserp-result_search-card"]")
for job_url_element in job_url_elements:
  job_url = job_url_element["href"]
  job_urls.append(job_url) 

select() renvoie tous les éléments correspondant au sélecteur CSS donné, qui contiennent des liens vers des offres d’emploi. Ensuite, le script :

  1. Itère à travers ces éléments
  2. Accède à l’attribut HTML href (l’URL de la page d’emploi)
  3. L’ajoute à la liste job_urls

Si vous n’êtes pas familier avec la logique ci-dessus, consultez notre guide sur le Scraping web avec Beautiful Soup.

À la fin de cette étape, votre fonction retrieve_job_urls() ressemblera à ceci :

def retrieve_job_urls(job_search_url):
    # Effectue une requête HTTP GET pour obtenir le code HTML de la page
    response = requests.get(job_search_url)

    # Accède au code HTML et l'analyse
    html = response.text
    soup = BeautifulSoup(html, "html.parser")

    # Où stocker les données extraites
    job_urls = []

    # Logique d'extraction
    job_url_elements = soup.select("[data-tracking-control-name="public_jobs_jserp-result_search-card"]")
    for job_url_element in job_url_elements:
      # Extraire l'URL de la page d'emploi et l'ajouter à la liste
      job_url = job_url_element["href"]
      job_urls.append(job_url)

    return job_urls

Vous pouvez appeler cette fonction sur la page cible comme ci-dessous :

public_job_search_url = "https://www.linkedin.com/jobs/search?keywords=Software%2BEngineer&location=New%20York%2C%20New%20York%2C%20United%20States&geoId=102571732&trk=public_jobs_jobs-search-bar_search-submit&position=1&pageNum=0"
job_urls = retrieve_job_urls(public_job_search_url)

Bravo ! Vous avez terminé la première tâche de votre scraper LinkedIn.

Étape n° 6 : initialiser la tâche de scraping des données d’emploi

Concentrez-vous maintenant sur la fonction scrape_job(). Comme précédemment, utilisez la bibliothèque requests pour récupérer le code HTML de la page d’emploi à partir de l’URL fournie et analysez-le avec Beautiful Soup :

response = requests.get(job_url)

html = response.text
soup = BeautifulSoup(html, "html.parser")

Étant donné que le scraping des données d’emploi LinkedIn implique l’extraction de diverses informations, nous allons le décomposer en deux étapes afin de simplifier le processus.

Étape n° 7 : Récupération des données d’emploi — Partie 1

Avant de vous lancer dans le scraping des données LinkedIn, vous devez inspecter une page de détails d’offre d’emploi pour comprendre quelles données elle contient et comment les récupérer.

Pour ce faire, ouvrez une page d’offre d’emploi en mode navigation privée et utilisez les outils de développement pour inspecter la page. Concentrez-vous sur la partie supérieure de la page de l’offre d’emploi :

The HTML code of the top section of the page

Notez que vous pouvez extraire les données suivantes :

  • Le titre du poste à partir de la balise <h1>
  • Le nom de l’entreprise qui propose le poste à partir de l’élément [data-tracking-control-name="public_jobs_topcard-org-name"]
  • Les informations sur le lieu de travail à partir de .topcard__flavor--bullet
  • Le nombre de candidats à partir du nœud .num-applicants__caption

Dans la fonction scrape_job(), après avoir effectué l’analyse du code HTML, utilisez la logique suivante pour extraire ces champs :

title_element = soup.select_one("h1")
title = title_element.get_text().strip()

company_element = soup.select_one("[data-tracking-control-name="public_jobs_topcard-org-name"]")
company_name = company_element.get_text().strip()
company_url = company_element["href"]

location_element = soup.select_one(".topcard__flavor--bullet")
location = location_element.get_text().strip()

applicants_element = soup.select_one(".num-applicants__caption")
applicants = applicants_element.get_text().strip()

La fonction strip() est nécessaire pour supprimer les espaces avant et après le texte extrait.

Ensuite, concentrez-vous sur la section « salaire » de la page :
The HTML code of the salary section

Vous pouvez récupérer ces informations grâce au sélecteur CSS .salary. Étant donné que tous les postes ne comportent pas cette section, vous devez utiliser une logique supplémentaire pour vérifier si l’élément HTML est présent sur la page :

salary_element = soup.select_one(".salary")
if salary_element is not None:
    salary = salary_element.get_text().strip()
else:
    salary = None

Lorsque .salary n’est pas présent sur la page, select_one() renvoie None, et la variable salary est définie sur None.

Super ! Vous venez d’extraire une partie des données d’une page d’offre d’emploi LinkedIn.

Étape n° 8 : Récupération des données sur l’emploi — Partie 2

Concentrez-vous maintenant sur la partie inférieure de la page d’offre d’emploi LinkedIn, en commençant par la description du poste :

The HTML code of the salary section

Vous pouvez accéder au texte de la description du poste à partir de l’élément .description__text .show-more-less-html à l’aide de ce code :

description_element = soup.select_one(".description__text .show-more-less-html")
description = description_element.get_text().strip()

Enfin, la partie la plus difficile du Scraping web sur LinkedIn est le traitement de la section des critères :

The HTML code of the criteria section

Dans ce cas, vous ne pouvez pas prédire exactement quelles données seront présentes sur la page. Vous devez donc traiter chaque entrée comme une paire <nom, valeur>. Pour extraire les données des critères :

  1. Sélectionnez l’élément <ul> à l’aide du sélecteur CSS .description__job-criteria-list li
  2. Itérez sur les éléments sélectionnés, et pour chacun d’entre eux :
    1. Récupérez le nom de l’élément à partir de .description__job-criteria-subheader
    2. Extrayez la valeur de l’élément à partir de .description__job-criteria-text
    3. Ajoutez les données extraites sous forme de dictionnaire à un tableau

Implémentez la logique de récupération LinkedIn pour la section des critères à l’aide des lignes de code suivantes :

criteria = []
criteria_elements = soup.select(".description__job-criteria-list li")
for criteria_element in criteria_elements:
    name_element = criteria_element.select_one(".description__job-criteria-subheader")
    name = name_element.get_text().strip()

    value_element = criteria_element.select_one(".description__job-criteria-text")
    value = value_element.get_text().strip()

    criteria.append({
        "name": name,
        "value": value
    })

Parfait ! Vous venez de récupérer avec succès les données relatives à l’offre d’emploi. L’étape suivante consiste à rassembler toutes les données récupérées sur LinkedIn dans un objet et à les renvoyer.

Étape n° 9 : rassembler les données récupérées

Utilisez les données récupérées lors des deux étapes précédentes pour remplir un objet d'emploi et le renvoyer à partir de la fonction :

job = {
    "url": job_url,
    "title": title,
    "company": {
        "name": company_name,
        "url": company_url
    },
    « location » : location,
    « applications » : applicants,
    « salary » : salary,
    « description » : description,
    « criteria » : criteria
}
return job 

Une fois les trois étapes précédentes terminées, scrape_job() devrait ressembler à ceci :

def scrape_job(job_url) :
    # Envoyer une requête HTTP GET pour récupérer le code HTML de la page.
    response = requests.get(job_url)

    # Accéder au texte HTML de la réponse et l'analyser.
    html = response.text
    soup = BeautifulSoup(html, "html.parser")

    # Logique de scraping
    title_element = soup.select_one("h1")
    title = title_element.get_text().strip()

    company_element = soup.select_one("[data-tracking-control-name="public_jobs_topcard-org-name"]")
    company_name = company_element.get_text().strip()
    company_url = company_element["href"]

    location_element = soup.select_one(".topcard__flavor--bullet")
    location = location_element.get_text().strip()

    applicants_element = soup.select_one(".num-applicants__caption")
    applicants = applicants_element.get_text().strip()

    salary_element = soup.select_one(".salary")
    if salary_element is not None:
      salary = salary_element.get_text().strip()
    else:
       salary = None

    description_element = soup.select_one(".description__text .show-more-less-html")
    description = description_element.get_text().strip()

    criteria = []
    criteria_elements = soup.select(".description__job-criteria-list li")
    for criteria_element in criteria_elements:
        name_element = criteria_element.select_one(".description__job-criteria-subheader")
        name = name_element.get_text().strip()

        value_element = criteria_element.select_one(".description__job-criteria-text")
        value = value_element.get_text().strip()

        criteria.append({
            "name": name,
            "value": value
        })

    # Collecter les données extraites et les renvoyer
    job = {
        "url": job_url,
        "title": title,
        "company": {
            "name": company_name,
            "url": company_url
        },
        "location": location,
        "applications": applicants,
        "salary": salary,
        "description": description,
        "criteria": criteria
    }
    return job

Pour collecter les données relatives aux offres d’emploi, appelez cette fonction en itérant sur les URL d’offres d’emploi renvoyées par retrieve_job_urls(). Ajoutez ensuite les données récupérées à un tableau d'offres d'emploi:

jobs = []
for job_url in job_urls:
    job = scrape_job(job_url)
    jobs.append(job)

Fantastique ! La logique de scraping des données LinkedIn est maintenant terminée.

Étape n° 10 : exporter au format JSON

Les données d’emploi extraites de LinkedIn sont désormais stockées dans un tableau d’objets. Comme ces objets ne sont pas plats, il est logique d’exporter ces données dans un format structuré tel que JSON.

Python vous permet d’exporter des données vers JSON sans avoir besoin de dépendances supplémentaires. Pour ce faire, vous pouvez utiliser la logique suivante :

file_name = "jobs.json"
with open(file_name, "w", encoding="utf-8") as file:
    json.dump(jobs, file, indent=4, ensure_ascii=False)

La fonction open() crée le fichier de sortie jobs.json, qui est ensuite rempli avec json.dump(). L'indent=4 garantit que le JSON est formaté pour être lisible, et ensure_ascii=False garantit que les caractères non ASCII sont correctement encodés.

Pour que le code fonctionne, n’oubliez pas d’importer json depuis la bibliothèque standard Python :

import json 

Étape n° 11 : finaliser la logique de scraping

À présent, le script de scraping LinkedIn est pratiquement terminé. Cependant, vous pouvez encore apporter quelques améliorations :

  1. Limiter le nombre de tâches scrapées
  2. Ajoutez des journaux pour surveiller la progression du script

Le premier point est important pour la raison suivante :

  1. Vous ne voulez pas surcharger le serveur cible avec trop de requêtes provenant de votre scraper LinkedIn
  2. Vous ne savez pas combien de tâches se trouvent sur une seule page

Il est donc logique de limiter le nombre de tâches récupérées comme suit :

scraping_limit = 10
jobs_to_scrape = job_urls[:scraping_limit]

jobs = []
for job_url in jobs_to_scrape:
    # ...

Cela limitera le nombre de pages scrapées à 10.

Ajoutez ensuite quelques instructions print() pour surveiller ce que fait le script pendant son exécution :

public_job_search_url = "https://www.linkedin.com/jobs/search?keywords=Software%2BEngineer&location=New%20York%2C%20New%20York%2C%20United%20States&geoId=102571732&trk=public_jobs_jobs-search-bar_search-submit&position=1&pageNum=0"

print("Démarrage de la récupération des offres d'emploi à partir de l'URL de recherche LinkedIn...")

job_urls = retrieve_job_urls(public_job_search_url)

print(f"Récupération de {len(job_urls)} URL d'emploi sn")

scraping_limit = 10
jobs_to_scrape = job_urls[:scraping_limit]

print(f"Récupération de {len(jobs_to_scrape)} emplois...n")

jobs = []
for job_url in jobs_to_scrape:
    print(f"Extraction des données en cours sur "{job_url}"")

    job = scrape_job(job_url)
    jobs.append(job)

    print(f"Offre d'emploi récupérée")

print(f"nExportation de {len(jobs)} offres d'emploi récupérées au format JSON")
file_name = "jobs.json"
with open(file_name, "w", encoding="utf-8") as file:
    json.dump(jobs, file, indent=4, ensure_ascii=False)

print(f"Jobs successfully saved to "{file_name}"n")

La logique de journalisation vous aidera à suivre la progression du scraper, ce qui est essentiel étant donné qu’il passe par plusieurs étapes.

Étape n° 12 : assembler le tout

Voici le code final de votre script de scraping LinkedIn :

from bs4 import BeautifulSoup
import requests
import json

def retrieve_job_urls(job_search_url):
    # Effectuer une requête HTTP GET pour obtenir le code HTML de la page
    response = requests.get(job_search_url)

    # Accéder au code HTML et l'analyser
    html = response.text
    soup = BeautifulSoup(html, "html.parser")

    # Où stocker les données récupérées
    job_urls = []

    # Logique de scraping
    job_url_elements = soup.select("[data-tracking-control-name="public_jobs_jserp-result_search-card"]")
    for job_url_element in job_url_elements:
      # Extraire l'URL de la page d'emploi et l'ajouter à la liste
      job_url = job_url_element["href"]
      job_urls.append(job_url)

    return job_urls

def scrape_job(job_url):
    # Envoyer une requête HTTP GET pour récupérer le code HTML de la page
    response = requests.get(job_url)

    # Accéder au texte HTML de la réponse et l'analyser
    html = response.text
    soup = BeautifulSoup(html, "html.parser")

    # Logique de scraping
    title_element = soup.select_one("h1")
    title = title_element.get_text().strip()

    company_element = soup.select_one("[data-tracking-control-name="public_jobs_topcard-org-name"]")
    company_name = company_element.get_text().strip()
    company_url = company_element["href"]

    location_element = soup.select_one(".topcard__flavor--bullet")
    location = location_element.get_text().strip()

    applicants_element = soup.select_one(".num-applicants__caption")
    applicants = applicants_element.get_text().strip()

    salary_element = soup.select_one(".salary")
    if salary_element is not None:
      salary = salary_element.get_text().strip()
    else:
       salary = None

    description_element = soup.select_one(".description__text .show-more-less-html")
    description = description_element.get_text().strip()

    criteria = []
    criteria_elements = soup.select(".description__job-criteria-list li")
    for criteria_element in criteria_elements:
        name_element = criteria_element.select_one(".description__job-criteria-subheader")
        name = name_element.get_text().strip()

        value_element = criteria_element.select_one(".description__job-criteria-text")
        value = value_element.get_text().strip()

        criteria.append({
            "name": name,
            "value": value
        })

    # Collecter les données extraites et les renvoyer
    job = {
        "url": job_url,
        "title": title,
        "company": {
            "name": company_name,
            "url": company_url
        },
        "location": location,
        "applications": applicants,
        "salary": salary,
        "description": description,
        "criteria": criteria
    }
    return job

# URL publique de la page de recherche d'emplois LinkedIn
public_job_search_url = "https://www.linkedin.com/jobs/search?keywords=Software%2BEngineer&location=New%20York%2C%20New%20York%2C%20United%20States&geoId=102571732&trk=public_jobs_jobs-search-bar_search-submit&position=1&pageNum=0"

print("Démarrage de la récupération des offres d'emploi à partir de l'URL de recherche LinkedIn...")

# Récupération des URL individuelles pour chaque offre d'emploi sur la page
job_urls = retrieve_job_urls(public_job_search_url)

print(f"Récupération de {len(job_urls)} URL d'offres d'emploin")

# Récupération d'un maximum de 10 offres d'emploi sur la page
scraping_limit = 10
jobs_to_scrape = job_urls[:scraping_limit]

print(f"Récupération de {len(jobs_to_scrape)} offres d'emploi...n")

# Récupérer les données de chaque page d'offre d'emploi
jobs = []
for job_url in jobs_to_scrape:
    print(f"Extraction des données en cours sur "{job_url}"")

    job = scrape_job(job_url)
    jobs.append(job)

    print(f"Offre d'emploi récupérée")

# Exporter les données récupérées au format CSV
print(f"nExportation de {len(jobs)} emplois récupérés au format JSON")
file_name = "jobs.json"
with open(file_name, "w", encoding="utf-8") as file:
    json.dump(jobs, file, indent=4, ensure_ascii=False)

print(f"Emplois enregistrés avec succès dans "{file_name}"n")

Lancez-le avec la commande suivante :

python scraper.py

Le scraper LinkedIn devrait enregistrer les informations suivantes :

Démarrage de la récupération des offres d'emploi à partir de l'URL de recherche LinkedIn...
60 URL d'offres d'emploi récupérées                                                                                                        
Récupération de 10 offres d'emploi...

Démarrage de l'extraction des données sur « https://www.linkedin.com/jobs/view/software-engineer-recent-graduate-at-paypal-4149786397?position=1&pageNum=0&refId=nz9sNo7HULREru1eS2L9nA%3D%3D&trackingId=uswFC6EjKkfCPcv0ykaojw%3D%3D »
Offre d'emploi récupérée

# omis pour plus de concision...

Début de l'extraction des données sur « https://www.linkedin.com/jobs/view/software-engineer-full-stack-at-paces-4090771382 ?position=2&pageNum=0&refId=UKcPcvFZMOsZrn0WhZYqtg%3D%3D&trackingId=p6UUa6cgbpYS1gDkRlHV2g%3D%3D"
Offre d'emploi récupérée

Exportation de 10 offres d'emploi récupérées vers JSON
Offres d'emploi enregistrées avec succès dans « jobs.json »

Sur les 60 pages d’offres d’emploi trouvées, le script n’a récupéré que 10 offres. Par conséquent, le fichier de sortie jobs.json généré par le script contiendra exactement 10 offres d’emploi :

[
    {
        "url": "https://www.linkedin.com/jobs/view/software-engineer-recent-graduate-at-paypal-4149786397?position=1&pageNum=0&refId=UKcPcvFZMOsZrn0WhZYqtg%3D%3D&trackingId=UzOyWl8Jipb1TFAGlLJxqw%3D%3D",
        « title » : « Ingénieur logiciel - Jeune diplômé »,
        « company » : {
            « name » : « PayPal »,
            « url » : « https://www.linkedin.com/company/paypal?trk=public_jobs_topcard-org-name »
        },
        "location": "New York, NY",
        "applications": "Plus de 200 candidats",
        "salary": null,
        "description": "Omis pour plus de concision...",
        « critères » : [
            {
                « nom » : « Niveau d'ancienneté »,
                « valeur » : « Sans objet »
            },
            {
                « nom » : « Type d'emploi »,
                « valeur » : « Temps plein »
            },
            {
                « nom » : « Fonction »,
                « valeur » : « Ingénierie »
            },
            {
                « nom » : « Secteurs d'activité »,
                « valeur » : « Développement de logiciels, services financiers, technologie, information et Internet »
            }
        ]
    },

    // 8 autres postes...

    {
        "url": "https://www.linkedin.com/jobs/view/software-engineer-full-stack-at-paces-4090771382?position=2&pageNum=0&refId=UKcPcvFZMOsZrn0WhZYqtg%3D%3D&trackingId=p6UUa6cgbpYS1gDkRlHV2g%3D%3D",
        « title » : « Ingénieur logiciel (Full-Stack) »,
        « company » : {
            « name » : « Paces »,
            « url » : « https://www.linkedin.com/company/pacesai?trk=public_jobs_topcard-org-name »
        },
        « location » : « Brooklyn, NY »,
        « applications » : « Plus de 200 candidats »,
        « salary » : « 150 000,00 $/an - 200 000,00 $/an »,
        « description » : « Omis pour plus de concision... »,
        « criteria » : [
            {
                « name » : « Niveau d'ancienneté »,
                « value » : « Débutant »
            },
            {
                « name » : « Type d'emploi »,
                « value » : « Temps plein »
            },
            {
                « nom » : « Fonction »,
                « valeur » : « Ingénierie et technologies de l'information »
            },
            {
                « nom » : « Secteurs d'activité »,
                « valeur » : « Développement de logiciels »
            }
        ]
    },
]

Et voilà ! Le Scraping web de LinkedIn en Python n’est pas si difficile.

Rationaliser le scraping des données LinkedIn

Le script que nous avons créé peut donner l’impression que le scraping de LinkedIn est une tâche simple, mais ce n’est pas le cas. Le mur de connexion et les techniques d’obfuscation des données peuvent rapidement devenir des défis, en particulier lorsque vous développez votre opération de scraping.

De plus, LinkedIn a mis en place des mécanismes de limitation de débit pour bloquer les scripts automatisés qui effectuent trop de requêtes. Une solution courante consiste à faire tourner votre adresse IP dans Python, mais cela nécessite un effort supplémentaire.

De plus, n’oubliez pas que LinkedIn est en constante évolution, de sorte que les efforts et les coûts de maintenance de votre scraper ne sont pas négligeables. LinkedIn recèle une mine de données sous divers formats, des offres d’emploi aux articles. Pour récupérer toutes ces informations, vous devriez créer différents scrapers et les gérer tous.

Oubliez ces tracas grâce à l’API LinkedIn Scraper de Bright Data. Cet outil dédié peut extraire toutes les données LinkedIn dont vous avez besoin et les fournir via des intégrations sans code ou via des points de terminaison simples que vous pouvez appeler avec n’importe quel client HTTP.

Utilisez-le pour extraire des profils, des publications, des entreprises, des offres d’emploi et bien plus encore sur LinkedIn en quelques secondes, sans avoir à gérer toute une architecture de scraping.

Conclusion

Dans ce tutoriel étape par étape, vous avez appris ce qu’est un scraper LinkedIn et les types de données qu’il peut récupérer. Vous avez également créé un script Python pour scraper les offres d’emploi sur LinkedIn.

Le défi réside dans le fait que LinkedIn utilise des interdictions d’IP et des murs de connexion pour bloquer les scripts automatisés. Contournez ces problèmes grâce à notre scraper LinkedIn.

Si le Scraping web ne vous convient pas, mais que vous êtes toujours intéressé par les données, consultez nos jeux de données LinkedIn prêts à l’emploi !

Créez dès aujourd’hui un compte Bright Data gratuit pour essayer nos API de scraper ou explorer nos jeux de données.