Recherche d'un nom sur un site web

Fermé
Raph_0 Messages postés 7 Date d'inscription vendredi 28 juillet 2023 Statut Membre Dernière intervention 29 juillet 2023 - Modifié le 22 août 2023 à 15:28
Raph_0 Messages postés 7 Date d'inscription vendredi 28 juillet 2023 Statut Membre Dernière intervention 29 juillet 2023 - 29 juil. 2023 à 15:36

Bonjour tout le monde, je suis en train de coder un programme pour rechercher un membre de ma famille dans une liste de passagers de bateaux. Voici mon cahier des charges :

  1. Ouvrir le site : https://hebrewsurnames.com/ships
  2. Analyser le code source de la page
  3. Ouvrir le premier lien commençant par '/ships_'
  4. Attendre aléatoirement entre 3 et 5 secondes
  5. Analyser le code source de la page
  6. Ouvrir le premier lien commençant par 'arrival_'
  7. Pour chaque liens 'arrival_' ouverts prendre l'URL, la mettre dans le fichier "Results.csv" à la colonne 1
  8. Attendre aléatoirement entre 3 et 5 secondes
  9. Analyser le code source de la page
  10. Chercher si "PETTERSEN, TASTEIN" est écrit. Si oui laisser la page ouverte, si non la fermer.
  11. Si "PETTERSEN, TASTEIN" est écrit, écrire dans le fichier "Results.csv" OUI à la colonne 2 sinon écrire NON
  12. Attendre aléatoirement entre 3 et 5 secondes
  13. Analyser le code source de la page
  14. Chercher le lien 'arrival_' suivant et l'ouvrir
  15. Répéter ces actions ("7/" et "13/") jusqu'à qu'il n'y ai plus de lien 'arrival_'
  16. Fermer la page quand il n'y a plus de lien commençant par 'arrival_'
  17. Analyser le code source de la page
  18. Ouvrir le prochain lien commençant par '/ships_'
  19. Répéter les actions "2/" à "18/" jusqu'à ce qu'il n'y ait plus de liens commençant par '/ships_'

J'ai réussi à faire chercher au programme les noms dans tous les liens 'arrival_' du premier bateau, mais quand il a fini, au lieu de faire un retour au lien initial (liste des bateaux), le programme refait le tour du même bateau. Je suppose que c'est un problème de boucle mais je n'arrive pas à régler le problème.

Voici mon programme :

import random
import time
import csv
import requests
from bs4 import BeautifulSoup
import webbrowser

# Fonction pour ouvrir une page et retourner son contenu HTML
def get_page(url):
    response = requests.get(url)
    return response.content

# Fonction pour attendre un délai aléatoire entre 3 et 5 secondes
def wait_random():
    time.sleep(random.randint(3, 5))

# Fonction pour extraire les liens d'une page commençant par un certain préfixe
def get_links_with_prefix(page_content, prefix):
    soup = BeautifulSoup(page_content, 'html.parser')
    links = soup.find_all('a', href=True)
    return [link['href'] for link in links if link['href'].startswith(prefix)]

# Fonction pour vérifier si "PETTERSEN, TASTEIN" est présent dans le contenu de la page
def is_name_present(page_content):
    soup = BeautifulSoup(page_content, 'html.parser')
    return "PETTERSEN, TASTEIN" in soup.get_text()

# Fonction pour écrire dans le fichier "Results.csv" et ouvrir le lien dans le navigateur
def write_to_csv(url, result):
    with open('Results.csv', 'a', newline='') as csvfile:
        writer = csv.writer(csvfile)
        writer.writerow([url, result])

    # Ouvrir le lien dans le navigateur
    webbrowser.open(url)

# URL de départ
base_url = 'https://hebrewsurnames.com/ships'

# Étape 1 : Ouvrir le site et analyser le code source de la page
page_content = get_page(base_url)

# Étape 2 à 18 : (à l'intérieur d'une boucle pour les liens commençant par '/ships_')
ship_links = get_links_with_prefix(page_content, '/ships_')
for ship_link in ship_links:
    ship_url = 'https://hebrewsurnames.com' + ship_link
    # Étape 4 : Attendre aléatoirement entre 3 et 5 secondes
    wait_random()

    # Étape 5 : Analyser le code source de la page
    ship_page_content = get_page(ship_url)

    # Étape 6 : Ouvrir les liens commençant par 'arrival_'
    arrival_links = get_links_with_prefix(ship_page_content, 'arrival_')

    # Vérifier s'il y a des liens "arrival_" à explorer
    while arrival_links:
        # Stocker les liens "arrival_" à explorer pour le lien "/ship_"
        arrival_links_to_explore = arrival_links.copy()

        # Explorer tous les liens "arrival_" pour le lien "/ship_"
        for arrival_link in arrival_links_to_explore:
            arrival_url = 'https://hebrewsurnames.com/' + arrival_link

            # Étape 8 : Attendre aléatoirement entre 3 et 5 secondes
            wait_random()

            # Étape 9 et 10 : Chercher si "PETTERSEN, TASTEIN" est écrit
            arrival_page_content = get_page(arrival_url)
            if is_name_present(arrival_page_content):
                write_to_csv(arrival_url, 'OUI')
            else:
                write_to_csv(arrival_url, 'NON')

            # Étape 12 : Attendre aléatoirement entre 3 et 5 secondes
            wait_random()

        # Mettre à jour les liens "arrival_" après l'exploration pour le lien "/ship_"
        ship_page_content = get_page(ship_url)
        arrival_links = get_links_with_prefix(ship_page_content, 'arrival_')

print("Exploration terminée.")

Merci à vous d'avance.

A voir également:

8 réponses

expertsinformatique Messages postés 8 Date d'inscription vendredi 28 juillet 2023 Statut Membre Dernière intervention 14 juillet 2024
28 juil. 2023 à 16:25

Bonjour,

Le problème vient tout simplement du fait de "while arrival_links", pour vérifier la présence de arrival_links, ça marche, sauf que vous faites rentrer le programme dans une boucle infinie, le programme refait donc le tour du même bateau indéfiniment. 

Solution :

Il suffit de remplacer while par if.

Merci pour votre retour

0
Raph_0 Messages postés 7 Date d'inscription vendredi 28 juillet 2023 Statut Membre Dernière intervention 29 juillet 2023 2
28 juil. 2023 à 16:38

Bonjour expertsinformatique,

Je vous remercie de  votre réponse. J'ai changé le "while" par "if" mais malheureusement j'obtient toujours le même problème (les liens du même bateaux sont fouillés).

if arrival_links:

        # Stocker les liens "arrival_" à explorer pour le lien "/ship_"

        arrival_links_to_explore = arrival_links.copy()

0
expertsinformatique Messages postés 8 Date d'inscription vendredi 28 juillet 2023 Statut Membre Dernière intervention 14 juillet 2024
28 juil. 2023 à 17:15

Pourtant, moi j'obtiens

https://hebrewsurnames.com/arrival_A.R. DE GENOUILLY_1910-10-29    NON
https://hebrewsurnames.com/arrival_A.R. DE GENOUILLY_1911-04-01    NON
https://hebrewsurnames.com/arrival_A.R. DE GENOUILLY_1911-04-08    NON
https://hebrewsurnames.com/arrival_A.R. DE GENOUILLY_1911-08-02    NON
https://hebrewsurnames.com/arrival_A.R. DE GENOUILLY_1911-12-16    NON
https://hebrewsurnames.com/arrival_A.R. DE GENOUILLY_1912-04-01    NON
https://hebrewsurnames.com/arrival_A.R. DE GENOUILLY_1913-08-02    NON
https://hebrewsurnames.com/arrival_A.R. DE GENOUILLY_1915-06-01    NON
https://hebrewsurnames.com/arrival_A.R. DE GENOUILLY_1915-10-02    NON
https://hebrewsurnames.com/arrival_A.R. DE GENOUILLY_1920-06-01    NON
https://hebrewsurnames.com/arrival_A.R. DE GENOUILLY_1921-06-02    NON
https://hebrewsurnames.com/arrival_A.R. DE GENOUILLY_1929-12-03    NON
https://hebrewsurnames.com/arrival_A.S. DE LAMORNAIX_1906-03-02    NON
https://hebrewsurnames.com/arrival_A.S. DE LAMORNAIX_1906-07-01    NON
https://hebrewsurnames.com/arrival_A.S. DE LAMORNAIX_1907-02-02    NON
https://hebrewsurnames.com/arrival_A.S. DE LAMORNAIX_1907-06-02    NON
https://hebrewsurnames.com/arrival_A.S. DE LAMORNAIX_1907-10-01    NON
https://hebrewsurnames.com/arrival_A.S. DE LAMORNAIX_1908-06-02    NON
https://hebrewsurnames.com/arrival_A.S. DE LAMORNAIX_1908-10-12    NON
https://hebrewsurnames.com/arrival_A.S. DE LAMORNAIX_1909-05-03    NON
https://hebrewsurnames.com/arrival_A.S. DE LAMORNAIX_1909-09-01    NON
https://hebrewsurnames.com/arrival_A.S. DE LAMORNAIX_1910-05-09    NON
https://hebrewsurnames.com/arrival_A.S. DE LAMORNAIX_1910-08-02    NON
https://hebrewsurnames.com/arrival_A.S. DE LAMORNAIX_1911-05-01    NON


0
Raph_0 Messages postés 7 Date d'inscription vendredi 28 juillet 2023 Statut Membre Dernière intervention 29 juillet 2023 2
Modifié le 28 juil. 2023 à 21:29

Effectivement, vous avez raison. J'ai mis à jour mon éditeur et cela fonctionne.

Merci beaucoup !

2
jee pee Messages postés 40693 Date d'inscription mercredi 2 mai 2007 Statut Modérateur Dernière intervention 20 janvier 2025 9 497
Modifié le 28 juil. 2023 à 20:48

Bonjour,

Dans ton code je ne comprends pas pourquoi tu dupliques ta liste des arrivées, tu peux la traiter directement dans la boucle for, comme les bateaux.

Le soucis d'une arrivée traitée plusieurs fois, il faut regarder le source html, la liste à la fois des bateaux et des arrivées est à chaque fois présente 2 fois, pour un ecran pc et pour un ecran mobile.

Il faudrait peut être avec bs indiquer le bloc source à traiter si c'est possible. Pour tester je ne traite que la moitié de chaque liste :

import random
import time
import csv
import requests
from bs4 import BeautifulSoup
import webbrowser

# Fonction pour ouvrir une page et retourner son contenu HTML
def get_page(url):
    response = requests.get(url)
    return response.content

# Fonction pour attendre un délai aléatoire entre 3 et 5 secondes
def wait_random():
    time.sleep(random.randint(0, 0))

# Fonction pour extraire les liens d'une page commençant par un certain préfixe
def get_links_with_prefix(page_content, prefix):
    soup = BeautifulSoup(page_content, 'html.parser')
    links = soup.find_all('a', href=True)
    return [link['href'] for link in links if link['href'].startswith(prefix)]

# Fonction pour vérifier si person est présent dans le contenu de la page
def is_name_present(page_content, person):
    soup = BeautifulSoup(page_content, 'html.parser')
    return person in soup.get_text()

# Fonction pour écrire dans le fichier "Results.csv" et ouvrir le lien dans le navigateur
def write_to_csv(url, result):
    with open('Results.csv', 'a', newline='') as csvfile:
        writer = csv.writer(csvfile)
        writer.writerow([url, result])
    # Ouvrir le lien dans le navigateur
    # webbrowser.open(url)

# URL de départ
base_url = 'https://hebrewsurnames.com/ships'

# Étape 1 : Ouvrir le site et analyser le code source de la page
page_content = get_page(base_url)

# Étape 2 à 18 : (à l'intérieur d'une boucle pour les liens commençant par '/ships_')
ship_links = get_links_with_prefix(page_content, '/ships_')
print(ship_links[0:2], len(ship_links))
for ship_link in ship_links[0:int(len(ship_links)/2)]:
    ship_url = 'https://hebrewsurnames.com' + ship_link
    print(ship_url)
    # Étape 4 : Attendre aléatoirement entre 3 et 5 secondes
    wait_random()
    # Étape 5 : Analyser le code source de la page
    ship_page_content = get_page(ship_url)
    # Étape 6 : Ouvrir les liens commençant par 'arrival_'
    arrival_links = get_links_with_prefix(ship_page_content, 'arrival_')
    print(arrival_links, len(arrival_links))
    for arrival_link in arrival_links[0:int(len(arrival_links)/2)]:
        arrival_url = 'https://hebrewsurnames.com/' + arrival_link
        print(arrival_url)
        # Étape 9 et 10 : Chercher si xxx est présent
        arrival_page_content = get_page(arrival_url)
        if is_name_present(arrival_page_content,'AFA, ANTON'):
            write_to_csv(arrival_url, 'OUI')
        else:
            write_to_csv(arrival_url, 'NON')
        # Étape 12 : Attendre aléatoirement entre 3 et 5 secondes
        wait_random()

print("Exploration terminée.")
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
Raph_0 Messages postés 7 Date d'inscription vendredi 28 juillet 2023 Statut Membre Dernière intervention 29 juillet 2023 2
Modifié le 28 juil. 2023 à 21:29

Bonjour effectivement vous avez raison.

Si je comprends bien pour que le programme fouille tous les liens il suffit juste de supprimer "[0:int(len(arrival_links)/2)]" à la ligne 55 ?

Merci de votre aide.

0
jee pee Messages postés 40693 Date d'inscription mercredi 2 mai 2007 Statut Modérateur Dernière intervention 20 janvier 2025 9 497
28 juil. 2023 à 22:10

et en 45 aussi

mais en faisant cela chaque bateau est analysé 2 fois et chaque arrivée 2 fois, ce qui multiplie les analyses et le temps par 4

0
Raph_0 Messages postés 7 Date d'inscription vendredi 28 juillet 2023 Statut Membre Dernière intervention 29 juillet 2023 2
29 juil. 2023 à 12:25

Bonjour jee pee,

Effectivement chaque bateau est analysé 2 fois. Comment dois je faire pour régler ce problème ? Je ne suis pas très expérimenté en python.

J'ai pensé à faire une liste en stockant chaque liens fouillés et à chaque fois qu'il va pour fouiller un lien, il vérifie  si il est dans la liste. Si il y est il passe au suivant et si il n'y est pas il le fouille en le rajoutant dans la liste.

Je ne sais pas si cette solution est la plus rapide car j'ai peur que chaque vérification dans la liste prenne de plus en plus de temps au fur et à mesure.

J'aimerai savoir si vous (qui avait surement plus d'expérience que moi) validez ma solution ou si vous me conseillez de faire autrement.

Merci

0
Raph_0 Messages postés 7 Date d'inscription vendredi 28 juillet 2023 Statut Membre Dernière intervention 29 juillet 2023 2
Modifié le 29 juil. 2023 à 14:59

Mais si je ne traite que la 1ere moitié de la liste, l'autre restera non traité.

0
jee pee Messages postés 40693 Date d'inscription mercredi 2 mai 2007 Statut Modérateur Dernière intervention 20 janvier 2025 9 497
29 juil. 2023 à 15:19

Euh, affiches le contenu de la liste.

Si on ne traite que la moitié de la liste, c'est parce que chaque élément est présent 2 fois.

0
Raph_0 Messages postés 7 Date d'inscription vendredi 28 juillet 2023 Statut Membre Dernière intervention 29 juillet 2023 2 > jee pee Messages postés 40693 Date d'inscription mercredi 2 mai 2007 Statut Modérateur Dernière intervention 20 janvier 2025
29 juil. 2023 à 15:36

oui vous avez raison je m'en suis aperçut après avoir envoyé mon message.

Merci à vous pour votre aide.

0
jee pee Messages postés 40693 Date d'inscription mercredi 2 mai 2007 Statut Modérateur Dernière intervention 20 janvier 2025 9 497
29 juil. 2023 à 13:02

Ne traiter que la 1ere moitié de la liste comme je l'ai fait est une solution.

Tu peux aussi supprimer les doublons des listes bateau et arrivées

print(ship_links[0:2], len(ship_links))
ship_links = list(set(ship_links))
print(ship_links[0:2], len(ship_links))

Après il faudrait se pencher sur BS, et voir comment ne traiter que les lignes entre les 2 commentaires,

<!-- TABLA--> et <!-- MUESTRA DATOS MOBILE-->

-1