

# Comment fusionner des exports Bing sans perdre les traces des requêtes et des positions

Fusionnez les observations de résultats de recherche et les adresses cibles dans des tables distinctes pour conserver les données attestant les requêtes, les positions et les heures. Un Actor est un programme hébergé de collecte de données. Une Task est une configuration d’entrée enregistrée. Une canonicalUrl est une adresse candidate normalisée renvoyée par le programme, et non une URL canonique HTML vérifiée ou un href d’origine. Un snippet est un extrait fourni par le moteur de recherche source, et non le texte d’un article récupéré.

Configurez la version 1.0.15 de l’Apify Google Search Scraper en remplaçant entièrement les listes de requêtes et de moteurs de l’exemple enregistré par la requête voulue et `["bing"]`, avec ce JSON d’entrée : `{"queries": ["Python asyncio documentation"], "engines": ["bing"], "maxResultsPerExecutedQuery": 2, "country": "US", "language": "en", "safeSearch": true, "includeSponsoredResults": false}`. Notez que la version publique 1.0.15 prend en charge plusieurs moteurs, mais que seul Bing est validé ici ; les parcours Google, Brave et DuckDuckGo restent en attente ou sont exclus. Les compteurs du résumé d’exécution dans OUTPUT pour le test de contrôle indiquent : `queriesRequested`: 1, `searchesCompiled`: 1, `executionsPlanned`: 1, `enginesSuccessful`: 1, `enginesFailed`: 0, `pagesAttempted`: 1, `pagesParsed`: 1, `resultsSaved`: 2, `engineStatusCounts`: {"bing": {"ok": 1}}, `engineResultCounts`: {"bing": 2}, `queryResultCounts`: {"Python asyncio documentation": 2}, `stopReason`: "result_caps_reached". Ces compteurs reflètent les totaux de l’exécution du programme d’extraction, et non des lignes par cible. Ce test a confirmé, dans ce périmètre limité, la prise en charge des URL, des positions et de la provenance pour Bing. Il ne valide ni les autres moteurs non retenus, ni d’autres marchés, ni la récupération des pages de destination.

## 1. Définissez vos règles de collecte

1. Définissez vos règles de collecte en remplaçant entièrement les listes enregistrées de requêtes et de moteurs par 1 requête voulue et `["bing"]`, avec `maxResultsPerExecutedQuery: 2`, les États-Unis comme pays, l’anglais comme langue, `safeSearch: true` et `includeSponsoredResults: false`. Aucun paramètre public de limitation du nombre de pages n’est prescrit.
2. Enregistrez les lignes brutes des résultats Bing et les métadonnées OUTPUT. Les champs natifs des lignes comprennent `runId`, `country`, `language`, `safeSearch`, `engine`, `executedQuery`, `page`, `rankOnPage`, `rank`, `title`, `canonicalUrl`, `resultDomain`, `snippet`, `isSponsored`, `advertiserDomain`, `observedAt` et `schemaVersion`. Conservez toutes les informations qui identifient l’exécution et ses paramètres.
3. Construisez une clé d’observation à partir de `runId` + `engine` + `executedQuery` + `page` + `rankOnPage`. Conservez rank et observedAt comme éléments de preuve. Retirez de votre table de travail les lignes d’export strictement identiques et consignez chaque doublon. Si une clé répétée présente des valeurs d’URL contradictoires, mettez les 2 valeurs candidates en attente d’un examen de la source. Ne choisissez pas une valeur sans le signaler et ne vous fiez pas à la majorité.
4. Créez une clé de cible à partir de la `canonicalUrl` renvoyée : une adresse candidate normalisée, et non une preuve d’URL canonique HTML ou un href d’origine. Partez des chaînes d’URL exactes qui ont été renvoyées. Si vous normalisez la casse du nom d’hôte, les fragments ou les paramètres de suivi, consignez pourquoi la destination reste la même. Les chemins ou les paramètres de requête différents restent distincts.
5. Reliez les observations à la table des cibles au moyen d’une colonne de clé de cible. Une même URL trouvée par 2 requêtes ou à 2 moments différents correspond à plusieurs observations et à 1 cible examinée. L’association à une requête repose uniquement sur des observations réelles.
6. Exportez les tables de travail sans altérer les données. Préservez les guillemets, les virgules, les sauts de ligne et les caractères Unicode des requêtes. Utilisez le JSON ou le JSONL brut comme référence principale, car les outils d’export ou d’import CSV peuvent effacer la distinction entre une valeur nulle et une valeur vide. Vérifiez la restitution exacte après export et réimport avec un petit jeu de données de test avant de fusionner de grands exports.
7. Présentez des décomptes distincts pour les lignes brutes, les lignes d’export en double, les observations valides distinctes, les conflits et les clés de cible distinctes. Les URL distinctes ou les associations aux requêtes ne permettent pas d’estimer le volume total des recherches ni l’ensemble des sites web. Conservez les recherches en échec, sans résultat ou ayant atteint une limite dans votre compte rendu de collecte.
8. Transmettez les adresses cibles et les références des observations à une [vérification distincte des destinations](/fr/articles/file-exploration-resultats-bing/). La fusion des ressources ne prouve ni l’accès aux pages, ni leur pertinence, ni la fiabilité des sources. Précisez que le périmètre se limite à Bing.

## Registre de fusion fictif et contrôle des données

*Remarque : les tableaux et les enregistrements suivants sont des exemples fictifs originaux conçus à des fins pédagogiques.*

Imaginez un test où l’exécution R1 avec la requête "AI agents" donne U1 en position 1 et U2 en position 2. L’exécution R1 avec la requête "small business automation" donne U2 en position 1 et U3 en position 2. L’exécution R2 avec la requête "AI agents" donne U1 en position 1 et U4 en position 2. Tous sont des résultats Bing obtenus avec des paramètres déclarés identiques, chacun avec son propre horodatage. Les 6 clés d’observation correspondent à 4 clés de cible : U1, U2, U3 et U4. U1 compte 2 observations à des moments différents ; U2 compte 2 observations pour des requêtes différentes. Aucune de ces répétitions n’est une ligne d’export en double.

Une 7e ligne brute répète exactement R1 / requête "AI agents" / page 1 / position 2 U2. Elle reproduit à l’identique chaque valeur brute d’origine et constitue donc une ligne d’export en double. Une 8e ligne portant la même clé contient U9. La clé R1+bing+AI agents+1+2 présente un conflit pour U2 ET U9 ; mettez les 2 valeurs candidates en attente dans le registre des conflits au lieu de vous fier à la première valeur ou à la majorité. On conserve ainsi 8 lignes brutes, 1 ligne d’export en double, 6 clés d’observation, 1 clé en conflit, 5 observations sans conflit et 4 cibles validées. U9 reste exclue des cibles validées.

*Tableau fictif original de 8 lignes brutes.*

| RowId | RunId | Moteur | ExecutedQuery | Page | RankOnPage | CanonicalUrl | ObservedAt |
| --- | --- | --- | --- | --- | --- | --- | --- |
| 1 | R1 | bing | AI agents | 1 | 1 | U1 | 2026-10-13T06:20:15Z |
| 2 | R1 | bing | AI agents | 1 | 2 | U2 | 2026-10-13T06:20:15Z |
| 3 | R1 | bing | small business automation | 1 | 1 | U2 | 2026-10-13T06:21:00Z |
| 4 | R1 | bing | small business automation | 1 | 2 | U3 | 2026-10-13T06:21:00Z |
| 5 | R2 | bing | AI agents | 1 | 1 | U1 | 2026-10-13T07:00:15Z |
| 6 | R2 | bing | AI agents | 1 | 2 | U4 | 2026-10-13T07:00:15Z |
| 7 | R1 | bing | AI agents | 1 | 2 | U2 | 2026-10-13T06:20:15Z |
| 8 | R1 | bing | AI agents | 1 | 2 | U9 | 2026-10-13T06:20:15Z |

*Tableau fictif original des statuts de 6 clés.*

| ObservationKey | CandidateCanonicalUrl | Statut / État |
| --- | --- | --- |
| R1+bing+AI agents+1+1 | U1 | Sans conflit |
| R1+bing+AI agents+1+2 | U2, U9 | En attente pour conflit (les 2 valeurs candidates sont mises en attente ; la ligne 7 constitue la trace du doublon d’export) |
| R1+bing+small business automation+1+1 | U2 | Sans conflit |
| R1+bing+small business automation+1+2 | U3 | Sans conflit |
| R2+bing+AI agents+1+1 | U1 | Sans conflit |
| R2+bing+AI agents+1+2 | U4 | Sans conflit |

*Tableau fictif original de référence des cibles (4 cibles validées).*

| TargetKey | Références des observations sans conflit | Statut |
| --- | --- | --- |
| U1 | R1 AI agents position 1, R2 AI agents position 1 | Sans conflit |
| U2 | R1 small business automation position 1 | Sans conflit (conflit R1 AI agents position 2 mis en attente) |
| U3 | R1 small business automation position 2 | Sans conflit |
| U4 | R2 AI agents position 2 | Sans conflit |

*Petit jeu de données de test CSV fictif original contenant un saut de ligne intégré, des guillemets doublés, le mot Unicode café et une requête avec une virgule :*

Extrait de code

```text
runId,engine,executedQuery,page,rankOnPage,title,canonicalUrl
"R1","bing","garden, tray",1,1,"Café guide
""Best picks""","https://example.com/garden"
```

Registre de fusion fictif et contrôle des données

*Valeurs décodées du jeu de données de test et vérification par le lecteur :* Le champ de requête se décode en `garden, tray`. Le champ de titre se décode en `Café guide`, suivi d’un véritable saut de ligne et d’une seule paire de guillemets autour de `Best picks`. Le champ canonicalUrl se décode en la chaîne simple `https://example.com/garden` sans syntaxe Markdown. Une vérification par le lecteur après export et réimport confirme que la séparation par virgules, les sauts de ligne intégrés, les paires uniques de guillemets et les caractères Unicode sont correctement préservés. Toute affirmation selon laquelle une analyse, une écriture ou une lecture en Python a été effectuée s’applique uniquement à ce jeu de données fictif, jamais à un export d’Actor ou à un grand jeu de données.

## Étape suivante

Examinez votre configuration de collecte de données à l’aide de l’[Actor Google Search Scraper](https://apify.com/chronometrica/google-search-scraper) officiel et de la [Task Export Search Results to CSV](https://apify.com/chronometrica/google-search-scraper/examples/export-search-results-to-csv) pour récupérer vos observations Bing brutes et résoudre les écarts avant de supprimer les URL répétées.

## Sources et lectures complémentaires

- [Automatiser la recherche d’URL pour l’extraction de données](https://www.reddit.com/r/learnpython/comments/f96o07/automate_the_process_of_finding_urls_for_scraping/)