Introduction

Sachant que LinkedIn est connu pour bloquer l'automatisation lors de la récupération de ses données, comment garantir le succès de l'obtention de ces données de profil professionnel très recherchées pour votre entreprise ?

Si c’est un problème majeur que vous souhaitez résoudre, alors vous allez vous régaler.

Crawlbase est pleinement conscient des nombreuses opportunités offertes par l'exploration de données LinkedIn. En tant que pionnier de l'exploration Internet, Crawlbase se spécialise dans l'acquisition de données LinkedIn et dispose d'un algorithme unique qui garantit une expérience de scraping réussie, spécialement adaptée aux données LinkedIn.

Comprendre la portée du projet

Ce guide vous montrera comment construire un serveur de rappel résilient à l'aide de Flask. Ce serveur agira comme le webhook pour le Crawlbase Crawler, facilitant la récupération asynchrone des profils d'utilisateurs LinkedIn. L'accent sera mis sur l'analyse de la section « expérience » et son enregistrement dans une base de données MySQL. Ce processus optimise la collecte de données essentielles qui peuvent être appliquées à :

  1. Recherche et recrutement de talents
  2. Développement des ressources humaines et du personnel
  3. Intelligence et analyse du marché
  4. Analyse prédictive des données
  5. Algorithmes d’IA et d’apprentissage automatique

Il est essentiel de respecter les conditions d’utilisation et les directives de confidentialité de LinkedIn lors du traitement de ces données. Crawlbase Interdit formellement l'extraction de données privées de LinkedIn ou de tout autre site. L'exemple présenté ici est basé uniquement sur des données accessibles au public et est destiné à des fins pédagogiques.

Commençons.

Sommaire :

Partie I : Préparation de l'environnement

a. Création Crawlbase Compte et activation de l'exploration LinkedIn
b. Configuration de la base de données MySQL
c. Structure des fichiers et des répertoires
d. Création d'un environnement virtuel en Python
e. Comment obtenir une liste de profils LinkedIn

Partie II : Rédaction des scripts pour le projet

a. Créez une définition ORM à l'aide de SQLAlchemy pour interagir avec votre base de données
b. Script pour envoyer des requêtes au Crawlbase Crawler
c. Création d'un serveur de rappel Flask
d. Script pour récupérer les données explorées et les stocker dans la base de données

Partie III : Exécution des scripts

a. Démarrer un service de tunneling local à l'aide de Ngrok
b. Exécutez le serveur de rappel
c. Test du serveur de rappel
d. Configuration du Crawlbase Crawler avec votre URL de rappel
e. Exécutez le processeur
f. Lancer le crawl

Partie IV: Crawler Le Monitoring

Partie VI : Conclusion

Partie VI : Questions fréquemment posées

Partie I : Préparation de l'environnement

A. Création Crawlbase Compte et activation de l'exploration LinkedIn

  1. Commencez par visiter le Crawlbase site Web et crées un compte.
  2. Allez à Page d'accord LinkedIn de lire et d'accepter les conditions.
  3. Ajoutez vos informations de facturation en accédant à la paramètres des informations de facturation.

B. Configuration de la base de données MySQL

Nous utiliserons MySQL car il s'agit d'un système de gestion de base de données relationnelle populaire et largement utilisé pour diverses applications. Dans cet exemple, j'utiliserai MySQL version 8. Si vous ne l'avez pas encore installé sur votre machine, rendez-vous sur le site manuel d'installation officiel de MySQL.

Après l'installation, ouvrez le client de ligne de commande MySQL. Vous serez invité à saisir le mot de passe de l'utilisateur root MySQL. Après avoir saisi le mot de passe, vous serez dans l'interface de ligne de commande MySQL. Vous pouvez ensuite exécuter les lignes de commande suivantes.

  1. Créer un nouvel utilisateur
1
CREATE UTILISATEUR 'linkedincrawler'@'hôte local' IDENTIFIÉ BY 'linked1nS3cret';

Le code crée un nouvel utilisateur MySQL nommé linkedincrawler avec le mot de passe linked1nS3cret, limité à la connexion à partir de la même machine (localhost).

  1. Créer une base de données
1
CREATE BASE DE DONNÉES linkedin_crawler_db;

Cette base de données sera un conteneur vide pouvant stocker des tables, des données et d'autres objets.

  1. Donner la permission
1
SUBVENTION TOUTES PRIVILÈGES ON base de données linkedin_crawler_db.* À 'linkedincrawler'@'hôte local';

Cela accordera à notre utilisateur tous les privilèges et autorisations sur la base de données nouvellement créée.

  1. Définir la base de données actuelle
1
UTILISER linkedin_crawler_db;

Cela sélectionnera notre base de données et dirigera toutes nos instructions vers elle.

  1. Maintenant, créons trois tables dans la base de données actuellement sélectionnée : crawl_requests, linkedin_profiles et linkedin_profile_experiences.

Pour crawl_requests sera la table principale qui servira de mécanisme pour suivre l'ensemble du processus d'exploration asynchrone.

Dans ce tableau, nous aurons 3 colonnes : url, status, crawlbase_rid.

Pour status la colonne peut avoir l'une de ces trois valeurs - waiting, receiving et processed. La finalité de ces statuts sera précisée ultérieurement.

1
2
3
4
5
6
CREER LA TABLE IF ne pas EXISTE `crawl_requests` (
`Id` INT INCRÉMENTATION AUTOMATIQUE Clé principale,
`url` TEXTE PAS NUL,
`statut` VARCHAR(30) PAS NUL,
`crawlbase_rid` VARCHAR(255) PAS NUL
);

Ensuite, nous créons une base de données d'index pour les performances de notre requête.

1
2
3
CREATE INDEX `idx_crawl_requests_status` ON `crawl_requests` (`statut`);
CREATE INDEX `idx_crawl_requests_crawlbase_rid` ON `crawl_requests` (`crawlbase_rid`);
CREATE INDEX `idx_crawl_requests_status_crawlbase_rid` ON `crawl_requests` (`status`, `crawlbase_rid`);

Pour les 2 derniers tableaux, il vous permettra de stocker les informations structurées sur les profils LinkedIn explorés et leurs détails associés.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
CREER LA TABLE IF ne pas EXISTE `linkedin_profiles` (
`Id` INT INCRÉMENTATION AUTOMATIQUE Clé principale,
`crawl_request_id` INT PAS NUL,
'titre' VARCHAR(255),
`titre` VARCHAR(255),
TEXTE « résumé »,

CLÉ ÉTRANGÈRE (`crawl_request_id`) Références `crawl_requests`(`id`)
);

CREER LA TABLE IF ne pas EXISTE `expériences_de_profil_linkedin` (
`Id` INT INCRÉMENTATION AUTOMATIQUE Clé principale,
`identifiant_du_profil_linkedin` INT PAS NUL,
'titre' VARCHAR(255),
`nom_de_l'entreprise` VARCHAR(255),
TEXTE `description`,
BIT `est_actuel` PAS NUL DEFAULT 0,

CLÉ ÉTRANGÈRE (`linkedin_profile_id`) Références `linkedin_profiles`(`id`)
);

Pour afficher les tables que vous avez créées dans votre base de données MySQL, utilisez des requêtes SQL dans l'interface de ligne de commande MySQL ou un outil client MySQL.

Interface de ligne de commande MySQL

C. Structure des fichiers et des répertoires

Il est important d'organiser vos fichiers lors de la configuration d'un environnement en Python. Assurez-vous que chacun d'entre eux sera enregistré sous le même répertoire de projet, comme indiqué ci-dessous :

Structure des fichiers et des répertoires

D. Création d'un environnement virtuel en Python

Un environnement virtuel est un espace isolé dans lequel vous pouvez installer des packages Python sans affecter l'installation Python à l'échelle du système. Il est utile pour gérer les dépendances entre différents projets.

Dans ce projet, nous utiliserons Python 3Assurez-vous de télécharger et d'installer la version appropriée.

Open Git bash ou terminal pour exécuter la commande suivante.

1
DOSSIER_PROJET$ python3 -m venv .venv

Une fois l'environnement virtuel créé, vous devez l'activer.

1
DOSSIER_PROJET$ . .venv/bin/activate

Créez un fichier texte dans votre dossier de projet et enregistrez-le sous PROJECT_FOLDER/requirements.txtCe fichier doit contenir les packages Python suivants dont dépendra notre projet.

1
2
3
4
5
Flacon
connecteur mysql-python
pyyaml
demandes
SQLAlchemy

Installez les dépendances à l'aide de pip commander.

1
DOSSIER_PROJET$ pip install -r requirements.txt

Dans le même répertoire, créez un fichier nommé PROJECT_FOLDER/settings.yml qui servira d'espace réservé pour votre Crawlbase (TCP) jeton et Crawler nom.

1
2
jeton: < >
robot d'exploration: mon nom de crawler

E. Comment obtenir une liste de profils LinkedIn

Pour obtenir une liste d'URL de profils LinkedIn, vous devez généralement collecter ces URL à partir de différentes sources, telles que des résultats de recherche, des connexions ou des profils publics. Voici quelques façons d'obtenir des URL de profil LinkedIn :

  1. Collecte manuelle :
  • Vous pouvez accéder manuellement aux profils LinkedIn et copier les URL à partir de la barre d'adresse de votre navigateur Web. Cette méthode convient à un nombre limité de profils.
  1. Résultats de recherche LinkedIn :
  • Utilisez la fonction de recherche de LinkedIn pour trouver des profils en fonction de critères spécifiques (par exemple, titre du poste, emplacement, secteur d'activité).
  • Copiez les URL des profils répertoriés dans les résultats de recherche.
  1. Profils des connexions :
  • Si vous êtes connecté à quelqu'un sur LinkedIn, vous pouvez visiter sa liste de relations et extraire les URL de profil à partir de là.
  1. API tierce :
  • Vous pouvez construire un grattoir séparé en utilisant Crawlbase pour automatiser la collecte des URL LinkedIn. Nous aborderons peut-être ce sujet dans un prochain article ; soyez donc vigilants.

Pour les besoins de cet article, nous avons fourni une liste d'URL LinkedIn à récupérer. Par défaut, nous avons configuré le fichier texte avec l' top 5 des personnalités les plus suivies sur LinkedIn.

Ce fichier se trouve dans PROJECT_FOLDER/urls.txt.

Remarque : que chaque ligne correspond à une URL valide. Si vous disposez d'URL facilement disponibles, vous pouvez modifier ce fichier texte et les ajouter à la liste.

Partie II : Rédaction des scripts pour le projet

A. Créez une définition ORM à l'aide de SQLAlchemy pour interagir avec votre base de données

Nous devons maintenant créer un script pour travailler avec des données liées à LinkedIn dans une base de données MySQL. Ce script commencera par importer les modules nécessaires depuis SQLAlchemy et le module de saisie pour les indications de type.

À des fins de démonstration, nous allons enregistrer ce script dans PROJECT_FOLDER/lib/database.py

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
de dactylographie         importer Liste
de sqlalchimie importer Clé étrangère
de sqlalchimie importer créer_moteur
de sqlalchemy.org importer Base déclarative
de sqlalchemy.org importer Session
de sqlalchemy.org importer Mappé
de sqlalchemy.org importer colonne_mappée
de sqlalchemy.org importer relations

classe Base(Base déclarative):
pass

classe Demande d'exploration(Base):
__nom_de_table__ = « requêtes d'exploration »

id: Mappé[int] = colonne_mappée(clé_primaire=Vrai)
url: mappé[str]
statut : Mappé[str]
crawlbase_rid : mappé[str]
linkedin_profile: Mappé[« Profil LinkedIn »] = relation(back_populates='crawl_request')

classe Profil Linkedin(Base):
__nom_de_table__ = « profils_linkedin »

id: Mappé[int] = colonne_mappée(clé_primaire=Vrai)
titre : Cartographié[str]
titre : Cartographié[str]
résumé : Cartographié[str]
crawl_request_id : mappé[int] = colonne_mappée(Clé_étrangère('crawl_requests.id'))
crawl_request : mappé[« Demande d'exploration »] = relation(back_populates='profile_linkedin')
expériences : cartographiées[Liste[« Expérience de profil LinkedIn »]] = relation(back_populates='profile_linkedin')

classe Profil LinkedinExpérience(Base):
__nom_de_table__ = 'expériences_de_profil_linkedin'

id: Mappé[int] = colonne_mappée(clé_primaire=Vrai)
titre : Cartographié[str]
nom_entreprise : mappé[str]
description : Cartographié[str]
is_current : mappé[bool]
linkedin_profile_id : mappé[int] = colonne_mappée(Clé_étrangère('linkedin_profiles.id'))
linkedin_profile: Mappé[« Profil LinkedIn »] = relation(back_populates='expériences')

def créer_une_session_de_base_de_données
chaîne_de_connexion = 'mysql+mysqlconnector://linkedincrawler:linked1nS3cret@localhost:3306/linkedin_crawler_db'
moteur = create_engine(chaîne_de_connexion, echo=Vrai)
retourner Session (moteur)

Ce code fournit une fonction permettant de créer une session d'interaction avec la base de données. Notez que le script que nous allons fournir suppose que vous avez installé les bibliothèques nécessaires et qu'un serveur MySQL est en cours d'exécution avec les détails de connexion spécifiés.

B. Script pour envoyer des requêtes au Crawlbase Crawler

Pour Crawlbase Crawler fonctionne de manière asynchrone dans un système push-pull qui utilise des URL de rappel. Lorsque vous envoyez des requêtes à Crawler, il attribue un RID unique à chaque demande. Le Crawler effectue en interne l'exploration jusqu'à ce qu'un réponse réussie est obtenue. Par la suite, cette réponse est transmise à votre webhook désigné, vous permettant de traiter puis de stocker les données dans votre base de données.

Pour plus de détails, vous pouvez consulter le documentation complète du système Crawlbase Crawler.

Le script commence par importer les modules nécessaires, notamment les requêtes pour effectuer des requêtes HTTP, urllib.parse pour l'encodage des URL, json pour la gestion des données JSON et JSONDecodeError pour la gestion des erreurs de décodage JSON.

À des fins de démonstration, nous allons enregistrer ce script dans PROJECT_FOLDER/crawl.py.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
importer demandes
importer urllib.parse
importer json
de json importer JSONDecodeErreur
de lib.utils importer enregistrer
de lib.utils importer paramètres_de_chargement
de lib.base de données importer Demande d'exploration
de lib.base de données importer créer_une_session_de_base_de_données

crawlbase_settings = load_settings()

crawlbase_token = crawlbase_settings.get('jeton')
crawlbase_crawler = crawlbase_settings.get('rampe')

if jeton crawlbase is Aucun or crawlbase_token.strip() == '':
impression('------------------------------------------------- -')
impression(« Veuillez définir votre Crawlbase jeton dans le settings.yml')
impression('------------------------------------------------- -')
sortie()

if crawlbase_crawler is Aucun or crawlbase_crawler.strip() == '':
impression('------------------------------------------------- ----')
impression(« Veuillez définir votre Crawlbase robot d'exploration dans le fichier settings.yml')
impression('------------------------------------------------- ----')
sortie()

URL du profil linkedin = ouvert('urls.txt', 'r').readlines()

if len(URL du profil linkedin) == 0:
impression('------------------------------------------------- -------------------------------------------------- --')
impression(« Aucune URL n'est disponible. Veuillez renseigner les URL dans « urls.txt » en les séparant par une nouvelle ligne. »)
impression('------------------------------------------------- -------------------------------------------------- --')
sortie()

Journal(« Je commence à ramper... »)

crawlbase_api_url = 'https://api.crawlbase.com?token={0}&callback=true&crawler={1}&url={2}&autoparse=true'

session = créer_une_session_de_base_de_données()

pour url in URL du profil linkedin :
url = url.strip()
encoded_url = urllib.parse.quote(url, safe='')
api_url = crawlbase_api_url.le format(crawlbase_token, crawlbase_crawler, url codée)

Journal(f'Demande d'exploration {URL}')

Essai:
réponse = requêtes.get(api_url)
json_response = json.loads(réponse.texte)
crawlbase_rid = json_response['débarrasser']
crawl_request = CrawlRequest(url=url, crawlbase_rid=crawlbase_rid, status='en attendant')
session.add(requête_d'exploration)
session.commit()
sauf Erreur de décodage JSON :
Journal(f'Une erreur s'est produite lors du décodage de la réponse json\n{réponse.texte}')
sauf:
Journal(f'Une erreur inconnue s'est produite lors de l'exploration {URL}')

Journal(« J'ai fini de ramper. »)

Le code lira les URL à partir du PROJECT_FOLDER/urls.txt et envoie chaque URL au Crawlbase API pour l'exploration, qui répondra ensuite avec un ID de requête, par exemple {”rid”: 12341234}. Le code créera une nouvelle entrée de ligne pour stocker le RID dans notre crawl_requests table avec un statut de waiting.

Veuillez noter que nous devrons insérer le correspondant crawlbase_token et mes crawlbase_crawler nom dans ce script que nous aborderons dans le guide plus tard.

C. Création d'un serveur de rappel Flask

Flacon est un micro framework web écrit en Python que nous utiliserons pour créer le serveur de rappel.

Assurez-vous que votre rappel est équipé pour effectuer le décodage base64 et la décompression gzip. Ceci est essentiel car le Crawler le moteur transmettra les données à votre point de terminaison de rappel en utilisant la méthode POST avec compression gzip et encodage base64.

À des fins de démonstration, nous allons enregistrer ce script dans PROJECT_FOLDER/callback_server.py.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
importer gzip
de ballon importer Flacon
de ballon importer jsonifier
de ballon importer demandez
de lib.utils importer enregistrer
de lib.base de données importer Demande d'exploration
de lib.base de données importer créer_une_session_de_base_de_données

app = Flacon (__ nom__)
session = créer_une_session_de_base_de_données()

@app.route('/crawlbase_crawler_callback', méthodes=['PUBLIER'])
def rappel du robot d'exploration
crawlbase_rid = requête.en-têtes.get('débarrasser')
content_encoding = requête.en-têtes.get(« Encodage de contenu »)
état_original = demande.en-têtes.get(« Statut d'origine »)
if (pas statut_original is Aucun):
statut_original = int(état_original.split(',')[0])
crawlbase_status = requête.en-têtes.get(« Statut PC »)
if (pas état de la base d'exploration is Aucun):
crawlbase_status = int(crawlbase_status.split(',')[0])

if crawlbase_rid is Aucun:
Journal(f'Crawlbase rid n'est pas défini.')
retourner ('', 204)

if crawlbase_rid == 'demande factice':
Journal(« Le serveur de rappel fonctionne »)
retourner ('', 204)

if crawlbase_status != 200:
Journal(f'Crawlbase le statut n'est pas 200.')
retourner ('', 204)

if statut_original != 200:
Journal(« Le statut d'origine n'est pas 200. »)
retourner ('', 204)

crawl_request_does_not_exist = session.query(CrawlRequest).filter_by(crawlbase_rid=crawlbase_rid, status='en attendant').d'abord() is Aucun

if crawl_request_n'existe pas :
Journal(f'Non Crawlbase débarrasser {crawlbase_rid} trouvé avec le statut « en attente ».)
retourner ('', 204)

crawl_request = session.query(CrawlRequest).filter_by(crawlbase_rid=crawlbase_rid, status='en attendant').scalaire()

corps = demande.données
if encodage_de_contenu == 'gzip':
Essai:
corps = gzip.decompress(corps)
sauf Erreur OS :
pass

avec ouvert(f'./données/{crawlbase_rid}.json', 'wb') as f:
f.write(corps)

crawl_request.status = 'reçu'
session.commit()

Journal(f'Crawlbase débarrasser {crawlbase_rid} 'a été reçu avec succès.')

retourner ('', 201)

if __nom__ == '__principale__':
app.run ()

Ce code configure une application Flask avec une route pour gérer les rappels effectués à partir du Crawlbase Crawler. Notez que le Crawlbase Crawler met les informations RID dans l'en-tête de requête nommé rid.

De plus, ce code vérifiera notre crawl_requests tableau pour le même RID avec un waiting statut, sinon la demande sera ignorée.

Il s'assure également que les en-têtes de la demande Original-Status et mes PC-Status sont des codes de réponse d'état de réussite HTTP 200 OK.

Une fois qu'il reçoit les données explorées du Crawler, il sera traité (décodé et décompressé) et enregistré dans le dossier de données, puis mettra à jour le statut du RID dans received.

D. Script pour récupérer les données explorées et les stocker dans la base de données

Ce code se charge de surveiller régulièrement l'état du RID dans notre table crawl_requests. Lorsqu'il détecte que l'état a été reçu, il lance le traitement des données pour renseigner les tables linkedin_profiles et linkedin_profiles_experiences. Une fois l'opération terminée, il met à jour l'état du RID sur traité.

À des fins de démonstration, nous allons enregistrer ce script dans PROJECT_FOLDER/process.py.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
importer json
importer calendrier
importer fois
de lib.utils importer enregistrer
de lib.utils importer est_itérable
de lib.base de données importer Demande d'exploration
de lib.base de données importer Profil Linkedin
de lib.base de données importer Profil LinkedinExpérience
de lib.base de données importer créer_une_session_de_base_de_données

INTERVALLE_PROGRAMMATION_EN_SECONDES = 60
LIMITE_DE_COMPTE_D'ENREGISTREMENTS_PAR_TRAITEMENT = 10

def processus
session = créer_une_session_de_base_de_données()
demandes_d'exploration_reçues = session.query(CrawlRequest).filter_by(status='reçu').limit(LIMITE_NOMBRE_D'ENREGISTREMENTS_PAR_TRAITEMENT).tous()

if len(requêtes d'exploration reçues) == 0:
Journal(« Aucune demande d'exploration reçue à traiter. »)
d'autre:
pour demande_d'exploration in demandes d'exploration reçues :
Journal(f'Traitement Crawlbase débarrasser {crawl_request.crawlbase_rid} avec l'URL {crawl_request.url}.')

f = ouvert(f'./données/{crawl_request.crawlbase_rid}.json')
données = json.load(f)

titre = données.get('Titre')
titre = data.get('titre')
résumés = data.get('résumé')
résumé = '\n'.join(résumés) if is_iterable(résumés) d'autre Aucun

linkedin_profile = LinkedinProfile(title=titre, headline=titre, summary=résumé)
linkedin_profile.crawl_request_id = demande_d'exploration.id
session.add(profil_linkedin)

expériences = (data.get('expérience') et mes données.get('expérience').obtenir('Liste d'expériences')) or []
pour L'Expérience in expériences:
titre = expérience.get('Titre')
nom_entreprise = expérience.get('entreprise') et mes expérience.get('entreprise').obtenir('nom')
descriptions = expérience.get('la description')
description = '\n'.join(descriptions) if is_iterable(descriptions) d'autre Aucun
is_current = expérience.get('position actuelle') == Vrai

linkedin_profile_experience = ExpérienceProfilLinkedin(
titre=titre,
company_name=nom_entreprise,
description=description,
est_actuel=est_actuel
)
linkedin_profile_experience.linkedin_profile = linkedin_profile
session.add(expérience_profil_linkedin)

crawl_request.status = 'traité'

session.commit()

def traiter_et_reprogrammer
traiter()
scheduler.enter(INTERVALLE_PROGRAMME_EN_SECONDES, 1, traiter_et_reprogrammer)

if __nom__ == '__principale__':
planificateur = sched.scheduler(temps.monotonique, temps.sommeil)
processus_et_reschedule()
planificateur.run()

Partie III : Exécution des scripts

A. Démarrer un service de tunneling local à l'aide de Ngrok

Ngrok est un outil qui crée des tunnels sécurisés vers localhost, vous permettant d'exposer temporairement votre application Web hébergée localement à Internet.

Créez une URL publique temporaire avec Ngrok qui pointera vers votre application hébergée localement. Cela nous permettra d'utiliser notre serveur de rappel Flask comme webhook vers l'application. Crawlbase Crawler.

1
$ ngrok http 5000

Une fois exécuté, récupérez l'URL publique que nous utiliserons plus tard pour créer notre Crawler.

Ngrok

Remarque : nous devons pointer ngrok vers le port 5000 en tant qu'application Flask callback_server.py sera par défaut sur le même port.

B. Exécutez le serveur de rappel

Maintenant que Ngrok a été initialisé, nous pouvons exécuter notre serveur de rappel qui récupérera les RID et le contenu exploré à partir de Crawlbase.

1
DOSSIER_PROJET $ python callback_server.py

Sur la base de notre code, voici l'itinéraire complet qui gère le rappel :

https://400d-120-29-87-188.ngrok.io/crawlbase_crawler_callback

C. Test du serveur de rappel

Nous devons nous assurer que le serveur de rappel fonctionne comme prévu et peut transmettre le Crawlbase exigencesPour ce faire, vous pouvez exécuter l’extrait de code suivant et observer le résultat :

1
$ curl -i -X ​​POST 'http://localhost:5000/crawlbase_crawler_callback' -H « RID : demande fictive » -H « Accepter : application/json » -H 'Type de contenu : gzip/json' -H 'Agent utilisateur : Crawlbase Surveillance Bot 1.0' -H « Codage de contenu : gzip » --données-binaire '"\x1F\x8B\b\x00+\xBA\x05d\x00\x03\xABV*\xCALQ\xB2RJ)\xCD\xCD\xAD,J-,M-.Q\xD2QJ\xCAO\xA9\x04\x8A*\xD5\x02\x00L\x06\xB1\xA7 \x00\x00\x00' --comprimé

Ce curl la commande fera une requête POST à ​​votre URL de rappel avec un en-tête HTTP personnalisé 'HTTP_RID' ajuster à 'test'.

Une fois l'exécution réussie, vous devriez recevoir une réponse identique à celle présentée ci-dessous :

[app][2023-08-10 17:42:16] Callback server is working

D. Configuration du Crawlbase Crawler avec votre URL de rappel

Maintenant que nous avons établi un serveur de rappel fonctionnel et conçu avec succès une base de données, il est temps de créer un Crawler et intégrer notre URL de rappel dans Crawlbase.

Connectez-vous à votre Crawlbase compte et accédez au Créer Crawler page. Tapez votre choix Crawler nommez et collez l'URL de rappel que nous avons créée précédemment.

Créer Crawler

Remarque : Crawlbase a attribué la requête normale (TCP) Crawler Pour LinkedIn, nous devons donc sélectionner cette option. Même si la requête « Normal » est sélectionnée, il est important de noter que Crawlbase Utilise des robots d'IA avancés dotés d'algorithmes conçus pour imiter le comportement humain. De plus, des proxys résidentiels premium sont utilisés pour améliorer le taux de réussite de chaque exploration.

E. Exécutez le processeur

Ouvrez une nouvelle console ou un nouveau terminal dans le même répertoire et activez-le.

1
DOSSIER_PROJET$ . .venv/bin/activate

Lancer le script process.py

1
DOSSIER_PROJET$ python process.py

Ce script doit s'exécuter en permanence en arrière-plan car il vérifie fréquemment les données qui proviendront du Crawlbase Crawler.

F. Commencer à ramper

Avant de lancer vos requêtes, assurez-vous d'avoir défini toutes les variables correctes dans vos scripts. Obtenez votre requête normale/jeton TCP à partir du Crawlbase compte Page.

Accédez au répertoire principal de votre projet, ouvrez le PROJECT_FOLDER/settings.yml fichier et ajoutez la valeur de votre jeton TCP et Crawler nom.

1
2
jeton: < >
robot d'exploration: LinkedIn-Crawler

Ouvrez une nouvelle console ou un nouveau terminal dans le même répertoire et activez-le.

1
DOSSIER_PROJET$ . .venv/bin/activate

Lancer le script crawl.py

1
DOSSIER_PROJET$ python crawl.py

Après avoir envoyé votre demande, vous devriez remarquer que votre crawl_requests la base de données sera renseignée avec l'URL en cours d'exploration, le RID de Crawlbase, et le statut correspondant comme indiqué dans la capture d'écran ci-dessous.

Demandes d'exploration

Partie IV: Crawler Le Monitoring

Pour Crawlbase Crawler est un système polyvalent qui offre des fonctionnalités utiles, notamment la surveillance en direct, qui sera pratique pour suivre l'état des demandes de notre robot d'exploration personnalisé en temps réel. Pour accéder à la page, naviguez simplement depuis votre Crawler tableau de bord et cliquez sur le Moniteur en direct languette.

Crawler moniteur en direct

Définition des termes

Explorations - Le nombre total d'explorations réussies

Échoue - Le nombre d'échecs d'exploration interne (gratuit)

Explorations simultanées - Le nombre de requêtes explorées simultanément à un moment donné.

Attendre - Les requêtes actuellement dans la file d'attente en attente d'être explorées.

Ensembles à réessayer - Le nombre de requêtes qui doivent être relancées. Crawler tentera d'explorer les URL cibles jusqu'à 110 tentatives ou jusqu'à ce qu'il obtienne une réponse réussie.

Une fois que le Crawler termine avec succès une exploration, il renverra les données à votre serveur de rappel. Par conséquent, il est essentiel de maintenir la disponibilité du serveur à tout moment. Votre table de base de données linkedin_profiles et linkedin_profile_experiences doit être mise à jour automatiquement une fois qu'elle reçoit les données extraites, éliminant ainsi le besoin d'intervention manuelle.

Partie V: Conclusion

Voici un organigramme simple des composants qui résume la portée de notre projet :

Organigramme des composants

Pour conclure, ce guide vous a emmené dans un voyage pour construire un profil LinkedIn efficace et hautement évolutif. Crawler en utilisant CrawlbaseFace aux défis de l'extraction de données sur LinkedIn, ce guide fournit une solution stratégique pour obtenir des informations précieuses sur les profils professionnels.

Crawlbase, pionnier de l'exploration web, propose un algorithme spécialisé conçu pour les données LinkedIn, garantissant une récupération fluide. Le projet vise à créer un serveur de rappel Flask capable de capturer efficacement les profils LinkedIn de manière asynchrone et de les stocker dans une base de données MySQL. Il est important de noter que seules les données accessibles au public sont utilisées, conformément aux conditions d'utilisation de LinkedIn.

De la configuration de l'environnement à l'exécution du code, en passant par l'écriture du script, ce guide couvre toutes les étapes cruciales. Vous progresserez en douceur en testant le serveur et en configurant le Crawlbase Crawleret lancer les demandes de données.

Crawler Le suivi offre des informations en temps réel à mesure que vous progressez, vous offrant ainsi un meilleur contrôle du processus. Grâce à ce guide, vous êtes prêt à exploiter toute la puissance de Crawlbase, créer un profil LinkedIn dynamique Crawler qui alimente vos projets avec des informations LinkedIn inestimables.

Enfin, rendez-vous sur GitHub si vous souhaitez récupérer la base de code complète de ce projet.

Partie VI : Questions fréquemment posées

Q : Comment envoyer des données supplémentaires à ma requête asynchrone et les récupérer sur mon serveur de rappel ?

Vous pouvez passer le callback_headers paramètre à votre demande. Par exemple, supposons que nous souhaitons ajouter des données supplémentaires telles que BATCH-ID et mes CUSTOMER-ID à chaque demande :

1
2
3
4
lot_id = 'un-lot-id'
ID client = 'un-identifiant-client'
en-têtes de rappel bruts = ID de lot :{token_id}|ID CLIENT :{customer_id}'
en-têtes_de_rappel_encodés = urllib.parse.quote(en-têtes_de_rappel_bruts, safe='')

Puis ajoutez le encoded_callback_headers au paramètre url dans la requête.

Mise en situation :

1
crawlbase_api_url = f'https://api.crawlbase.com?token=mynormaltoken&callback=true&crawler=LinkedIn-Crawler&url=https%3A%2F%2Fwww.linkedin.com%2Fin%2Fwilliamhgates%2F&autoparse=true&callback_headers={en-têtes de rappel codés}'

Vous pouvez récupérer ces valeurs dans notre serveur de rappel via les en-têtes de requête HTTP. Donc, dans notre exemple, BATCH-ID et mes CUSTOMER-ID sera récupéré comme :

1
2
batch_id = demande.en-têtes.get(« ID DE LOT »)
customer_id = request.headers.get(« ID CLIENT »)

Pour plus d'informations, veuillez visiter cette partie de la Crawlbase Documentation.

Q. Comment protéger mon webhook ?

Vous pouvez protéger le point de terminaison du webhook en utilisant n’importe quelle combinaison des méthodes suivantes :

  • Attachez un en-tête personnalisé à votre demande, contenant un jeton dont vous vérifierez la présence dans le webhook.
  • Utilisez un paramètre d'URL dans votre URL, en vérifiant son existence lors de la demande de webhook. Par exemple : votredomaine.com/2340JOiow43djoqe21rjosi?token=1234.
  • Limitez l'acceptation aux seules requêtes POST.
  • Vérifiez la présence d'en-têtes spécifiques anticipés, tels que Pc-Status, Original-Status, rid, etc.

En passant, nous déconseillons la mise sur liste blanche d'adresses IP car nos robots d'exploration peuvent provenir de différentes adresses IP et ces adresses IP peuvent changer sans préavis.

La légalité du scraping Web, comme le scraping de données LinkedIn, est complexe. Affaire hiQ Labs c. LinkedIn Corp., la Cour d'appel du neuvième circuit a statué que le scraping de données accessibles au public ne violait pas nécessairement la loi sur la fraude et les abus informatiques (Computer Fraud and Abuse Act, CFAA). Cependant, cela est spécifique à cette juridiction et à l'interprétation de la CFAA. La légalité du scraping Web dépend de facteurs tels que la nature des données, les méthodes utilisées, les accords et les lois de la juridiction.

Le piratage de contenu protégé par le droit d'auteur ou le non-respect des conditions d'utilisation peut entraîner des problèmes juridiques. Voici pourquoi Crawlbase autorise uniquement le scraping de données accessibles au public, c'est-à-dire de données auxquelles il est possible d'accéder sans session de connexion.

Si vous avez besoin de plus de précisions sur la manière dont cela s’applique à votre situation, il est recommandé de demander conseil à un professionnel du droit pour obtenir des conseils précis.

Q. Quels autres types de données utilisateur puis-je obtenir ? Crawlbase Grattoir LinkedIn ?

Les données les plus précieuses et les plus courantes à extraire des profils LinkedIn sont les suivantes :

  1. Nom : le nom complet de l'utilisateur.
  2. Titre/Profession : Une brève description du rôle professionnel ou de l'expertise de l'utilisateur.
  3. Nombre de connexions : le nombre de connexions de l'utilisateur sur LinkedIn.
  4. Localisation : L'emplacement géographique de l'utilisateur.
  5. Image de couverture : une image de bannière facultative affichée en haut du profil de l'utilisateur.
  6. Image de profil : la photo de profil de l'utilisateur.
  7. URL du profil : l'adresse Web unique du profil LinkedIn de l'utilisateur.
  8. Informations sur le poste : Détails sur les postes actuels et passés de l'utilisateur.
  9. Informations sur l'éducation : Informations sur le niveau d'éducation de l'utilisateur.
  10. Expérience : Un aperçu complet de l’expérience professionnelle et de l’historique de carrière de l’utilisateur.
  11. Activités : publications, articles et autres activités générés par les utilisateurs sur LinkedIn.
  12. Qualifications : Certifications ou qualifications supplémentaires obtenues par l'utilisateur.
  13. Organisations : détails sur les organisations auxquelles l'utilisateur est associé.

Q. Pourquoi utiliser Flask pour le webhook ?

  1. Personnalisation: Flask est un framework Web Python qui vous permet de créer un point de terminaison Webhook hautement personnalisable. Vous pouvez définir le comportement, l'authentification et la logique de traitement en fonction de vos besoins spécifiques.
  2. Flexibilité: Flask vous offre la flexibilité nécessaire pour gérer différents types de données entrantes, telles que JSON, les données de formulaire ou les fichiers. Ceci est important lorsque vous traitez différents types de charges utiles de webhook.
  3. Intégration: Les serveurs de rappel Flask peuvent facilement s'intégrer à vos applications ou services existants basés sur Python. Cela facilite l'intégration des données webhook dans vos flux de travail.
  4. Authentification et sécurité : Vous pouvez implémenter des mécanismes d'authentification et des mesures de sécurité au sein de votre serveur webhook Flask pour garantir que seules les sources autorisées peuvent déclencher le serveur.
  5. Débogage et journalisation : Flask fournit des outils de débogage et de journalisation, qui peuvent être incroyablement utiles pour surveiller le comportement de votre serveur webhook et diagnostiquer les problèmes.
  6. Mise à l'échelle et déploiement : Les applications Flask peuvent être déployées dans divers environnements d'hébergement, vous permettant de faire évoluer votre serveur webhook selon vos besoins.
  7. Communauté et ressources : Flask dispose d'une communauté large et active, ce qui signifie que vous pouvez facilement trouver des tutoriels, de la documentation et des packages tiers pour vous aider à créer et à maintenir votre serveur webhook.

Q. Pourquoi faire un crawl asynchrone plus complexe au lieu d'un crawl synchrone ?

L'exploration synchrone traite les tâches de manière séquentielle, ce qui peut être plus simple mais plus lent, en particulier lorsqu'il faut attendre. L'exploration asynchrone traite les tâches simultanément, ce qui améliore les performances et l'utilisation des ressources. Elle est également parfaite pour gérer un grand nombre de tâches simultanément.

La mise en œuvre est plus complexe et le débogage peut s'avérer plus complexe, mais dans ce cas, les avantages l'emportent largement sur les inconvénients. Voilà pourquoi Crawlbase encourage l'exploration asynchrone pour LinkedIn.