Bonjour à tous,
Je partage ici un script Python que j'ai développé pour automatiser la recherche de domaines pertinents afin d'y laisser des backlinks. Ce code est particulièrement utile pour les créateurs de contenu, blogueurs, ou propriétaires de sites web qui cherchent à améliorer leur référencement naturel en identifiant les forums ou sites adaptés à leur niche.
Je voulais trouver une alternative aux outils payants.
Fonctionnalités principales du script
Extraction et filtrage des domaines et URLs :
Analyse un fichier HTML (comme une page de résultats de recherche Google) pour extraire toutes les URLs.
Trie les URLs par domaine et exclut les doublons ou domaines déjà explorés.
ex : ce que vous pouvez faire mettre une commande google permettant de rechercher seulement des forums et qui contient les mots-clés "cheval" "poney" dans leurs pages, vous faites un crt+u puis vous enregistrer ctrl+s et vous le renommer recherche_google
Vérification de l’état des domaines :
Vérifie si les domaines sont actifs (pas de réponse 404).
Interaction avec OpenAI pour la pertinence :
Utilise l’API OpenAI pour évaluer si un domaine est pertinent pour votre niche.
Génère automatiquement une question adaptée pour poser sur un forum ou un blog en rapport avec votre thématique.
Vous aurez besoin de créer un api chatpgt
Sitemap et Backlinking :
A chaque lancement du code le code vas Analyser votre sitemap pour identifier les pages de votre site correspondant à la question générée.
Propose une URL de votre site à insérer dans votre message sur le forum pour maximiser l’efficacité du backlink.
Export des données :
Enregistre les résultats (domaines pertinents, URLs associées, questions générées, et URLs pour le backlink) dans un fichier CSV pour un suivi facile.
Le code créer créer un fichier know_domain qui permet d'ajouter a chaque fin de code les sites que vous aurrez déja eu dans le fichier csv, ça vous permet d'éviter d'avoir des domaines de forum sur lequels vous avez déja fait des bl desssus.
Un fichier CSV (backlinks.csv) sera généré, contenant :
Les domaines pertinents.
Les URLs associées.
Les questions optimisées pour chaque forum.
Les pages de votre site à utiliser pour le backlink.
Les points noirs du code :
- Peut optimiser, peut être bien plus améliorer
- Le code bug parfois sur les sorties, les urls associé ne correspond pas forcément(dépend de la taille du nombre de nouveau domaine que vous avez trouver, c'est pas le plus important, mais c'est relou tt de même) aux domaines pertinents, si vous trouvez la solution, je suis bien preneur, je galère un peu dessus.
-j'ai placé les résultats dans un fichier csv, mais perso je préfère travailler sur Google sheet donc il est possible de mettre son api Google pour mettre le résultat directement.
🔴 Hors ligne
voici le code :
# Initialiser le client OpenAI
client = OpenAI(
api_key=os.getenv("OPENAI_API_KEY"), # Vous pouvez définir directement la clé ici si nécessaire
)
# Fonction pour effectuer un appel OpenAI avec une pause
def call_openai_with_pause(api_function, *args, **kwargs):
response = api_function(*args, **kwargs)
time.sleep(1) # Pause de 1 seconde entre les appels
return response
# Fonction pour extraire et filtrer les domaines et les URLs depuis le fichier HTML
def extract_and_filter_domains_and_urls(file_path, previous_domains):
with open(file_path, 'r', encoding='utf-8') as file:
html_content = file.read()
soup = BeautifulSoup(html_content, 'lxml') # Utilisation de lxml pour plus de rapidité
links = soup.find_all('a', href=True)
domain_url_dict = {}
for link in links:
href = link['href']
if re.match(r'^https?://', href):
# Extraire le domaine depuis l'URL
domain_match = re.search(r'https?://([^/]+)', href)
if domain_match:
domain = domain_match.group(1)
# Stocker le premier lien trouvé pour chaque domaine
if domain not in domain_url_dict:
domain_url_dict[domain] = href
# Trier les domaines et les URLs pour garantir l'ordre
sorted_domains = sorted(domain_url_dict.keys())
sorted_urls = [domain_url_dict[domain] for domain in sorted_domains]
# Exclure les domaines déjà connus
filtered_domains = [domain for domain in sorted_domains if domain not in previous_domains]
filtered_urls = [domain_url_dict[domain] for domain in filtered_domains]
return filtered_domains, filtered_urls
# Fonction pour vérifier si un domaine renvoie une erreur 404
def check_404_status(domain):
try:
response = requests.head(f"http://{domain}", timeout=5)
return response.status_code != 404
except requests.RequestException:
return False
# Fonction optimisée pour interroger ChatGPT et générer les informations nécessaires
def generate_forum_details_parallel(domains, urls, sitemap_urls, topic="cheval"):
relevant_domains = []
relevant_urls = []
forum_titles = []
backlink_urls = []
def process_domain(domain, exact_url):
# Vérifier si le domaine est pertinent
completion = call_openai_with_pause(
client.chat.completions.create,
model="gpt-4o",
messages=[
{"role": "system", "content": "Tu es un assistant utile et tu peux déterminer si un site web est pertinent pour une thématique donnée."},
{"role": "user", "content": f"Le domaine {domain} est-il pertinent pour le thème suivant : {topic}? j'ai un site de blog qui parle sur le cheval, équitation, poney etc. Peux-tu me sortir les forums qui pourraient être les plus pertinents pour moi afin d'y laisser un message parlant de mon site pour faire du ninjalinking/backlinking ? Réponds par oui ou non."}
]
)
content = completion.choices[0].message.content.strip().lower()
if "oui" in content:
forum_title = generate_forum_question(domain, sitemap_urls)
backlink_url = select_backlink_url(domain, forum_title, sitemap_urls)
return domain, exact_url, forum_title, backlink_url
return None # Si le domaine n'est pas pertinent
def generate_forum_question(domain, sitemap_urls):
question_completion = call_openai_with_pause(
client.chat.completions.create,
model="gpt-4o",
messages=[
{"role": "system", "content": "Tu es un assistant utile et tu peux formuler des questions ou des problèmes pour des forums."},
{"role": "user", "content": f"Voici les articles disponibles sur mon site (sitemap) : {sitemap_urls}. Analyse le site {domain}. Propose une question ou un problème (70 caractères maximum) que je pourrais poser sur un forum lié au domaine {domain} et qui soit en lien avec des articles de mon site pour que je puisse faire un backlink plus tard sur mon site domain-cheval.com. Réponds uniquement par la question."}
]
)
return question_completion.choices[0].message.content.strip()
def select_backlink_url(domain, forum_title, sitemap_urls):
url_completion = call_openai_with_pause(
client.chat.completions.create,
model="gpt-4o",
messages=[
{"role": "system", "content": "Tu es un assistant utile et tu peux analyser un sitemap pour choisir une URL pertinente pour un backlink."},
{"role": "user", "content": f"Voici les articles disponibles sur mon site (sitemap) : {sitemap_urls}. Pour le domaine {domain} et la question suivante : '{forum_title}', quelle URL de mon site devrais-je utiliser pour faire un backlink ? Réponds uniquement par l'URL choisie, n'explique pas ton raisonnement."}
]
)
return url_completion.choices[0].message.content.strip()
# Utilisation de ThreadPoolExecutor pour un traitement parallèle
with ThreadPoolExecutor(max_workers=2) as executor:
results = executor.map(process_domain, domains, urls)
# Filtrer les résultats et les ajouter aux listes
for result in results:
if result: # Si le résultat n'est pas None (le domaine est pertinent)
domain, exact_url, forum_title, backlink_url = result
relevant_domains.append(domain)
relevant_urls.append(exact_url)
forum_titles.append(forum_title)
backlink_urls.append(backlink_url)
return relevant_domains, relevant_urls, forum_titles, backlink_urls
# Fonction pour récupérer les URLs de votre Sitemap depuis l'URL
def get_sitemap_urls(sitemap_url):
urls = []
response = requests.get(sitemap_url)
if response.status_code == 200:
tree = ET.ElementTree(ET.fromstring(response.text))
root = tree.getroot()
for url in root.findall('.//{http://www.sitemaps.org/schemas/sitemap/0.9}url/{http://www.sitemaps.org/schemas/sitemap/0.9}loc'):
urls.append(url.text)
return urls
# Fonction pour créer le fichier CSV sans réécrire les anciennes données
def create_csv(relevant_domains, relevant_urls, forum_titles, backlink_urls, output_file="backlinks.csv"):
# Ouvrir le fichier en mode append pour ne pas écraser les anciennes données
with open(output_file, mode='a', newline='', encoding='utf-8') as file:
writer = csv.writer(file, delimiter=',', quotechar='"', quoting=csv.QUOTE_ALL)
# Ajouter les nouvelles lignes uniquement si le fichier est vide
if file.tell() == 0:
writer.writerow(["Domaine", "URL Exacte", "Titre du Forum", "URL du Backlink"])
# Ajouter les nouvelles informations
for domain, exact_url, forum_title, backlink_url in zip(relevant_domains, relevant_urls, forum_titles, backlink_urls):
writer.writerow([domain, exact_url, forum_title, backlink_url])
# Fonction pour mettre à jour la liste des domaines
def update_known_domains(known_domains_file, new_domains):
# Lire les domaines existants dans le fichier
if os.path.exists(known_domains_file):
with open(known_domains_file, 'r', encoding='utf-8') as file:
existing_domains = file.read().splitlines()
else:
existing_domains = []
# Ajouter les nouveaux domaines à la liste existante, sans doublons
updated_domains = set(existing_domains + new_domains)
# Enregistrer la liste mise à jour dans le fichier
with open(known_domains_file, 'w', encoding='utf-8') as file:
for domain in updated_domains:
file.write(domain + "\n")
print(f"Liste des domaines mise à jour avec {len(new_domains)} nouveaux domaines.")
# Exemple d'utilisation
file_path = "recherche_google.html"
sitemap_url = "https://domain-cheval.com/sitemap.xml"
def load_known_domains(known_domains_file):
if os.path.exists(known_domains_file):
with open(known_domains_file, 'r', encoding='utf-8') as file:
return set(file.read().splitlines())
else:
return set()
previous_domains = load_known_domains("known_domains.txt")
domains, urls = extract_and_filter_domains_and_urls(file_path, previous_domains)
domains = [d for d in domains if check_404_status(d)] # Supprimer les domaines avec 404
sitemap_urls = get_sitemap_urls(sitemap_url)
topic = "thématique de votre site, ex : cheval"
relevant_domains, relevant_urls, forum_titles, backlink_urls = generate_forum_details_parallel(domains, urls, sitemap_urls, topic)
create_csv(relevant_domains, relevant_urls, forum_titles, backlink_urls)
new_relevant_domains = relevant_domains
known_domains_file = "known_domains.txt"
update_known_domains(known_domains_file, new_relevant_domains)
print("CSV créé avec succès et liste des domaines mise à jour !")
🔴 Hors ligne
pour l'api :
Ouvrez les paramètres système avancés :
Sur Windows, tapez Variables d'environnement dans le menu Démarrer.
Ajoutez une nouvelle variable utilisateur :
Nom : OPENAI_API_KEY
Valeur : votre_clé_API
Redémarrez votre terminal ou PowerShell.
Avez vous des avis sur ce que je pourrai ajuster, pourrai ajouter en plus dessus des petites suggestions pour améliorer tout ça, je suis preneur et si vous savez comment régler cette histoire d'url en sortie qui ne match pas avec le domaine.
🔴 Hors ligne