Partage
  • Partager sur Facebook
  • Partager sur Twitter

Scrapper des pages web en JS

    2 janvier 2025 à 18:00:51

    Pour quelqu'un sans compétences en dev et qui utilise ChatGpt pour créer des scripts en python pour scrap, vous avez des suggestions pour reproduire un clic "humain" sur une pagination et contenu en JS ? 😇 
    J'utilise Selenium. Le script va bien de page en page (je le vois via le navigateur en temps réel), mais c'est toujours le contenu de la page 1 qui s'affiche. Par contre dès que c'est moi qui clique sur le navigateur, le bon contenu est chargé. Une idée ? 

    J'ai généré ce code via chat gpt : 
    from selenium import webdriver
    from selenium.webdriver.common.by import By
    from selenium.webdriver.common.action_chains import ActionChains
    from selenium.webdriver.support.ui import WebDriverWait
    from selenium.webdriver.support import expected_conditions as EC
    import time
    import pandas as pd
    
    # Chemin vers le fichier Excel de sortie
    output_file = "/Users/marc/Desktop/Python/reviews.xlsx"
    
    # Initialiser Selenium
    options = webdriver.ChromeOptions()
    #options.add_argument("--headless")  # Exécuter en mode headless
    options.add_argument("--disable-gpu")
    options.add_argument("--window-size=1920,1080")
    driver = webdriver.Chrome(options=options)
    
    # URL de départ
    url = "https://www.hotelbreak.com/fr/reviews"
    driver.get(url)
    
    # Attendre que la page charge les avis
    wait = WebDriverWait(driver, 10)
    
    # Xpath de l'avis et du bouton suivant
    review_xpath = "/html/body/div[1]/div[3]/div[2]/div/div[1]/p"
    next_button_xpath = "//button[@aria-label='Go to next page']"
    
    # Liste pour stocker les avis
    reviews = []
    page_number = 1
    
    try:
        while True:
            print(f"Extraction des avis de la page {page_number}...")
    
            # Attendre et récupérer les avis sur la page actuelle
            wait.until(EC.presence_of_all_elements_located((By.XPATH, review_xpath)))
            review_elements = driver.find_elements(By.XPATH, review_xpath)
    
            # Ajouter les nouveaux avis
            for element in review_elements:
                review_text = element.text.strip()
                if review_text:
                    reviews.append(review_text)
    
            # Essayer de cliquer sur le bouton suivant
            try:
                next_button = wait.until(EC.element_to_be_clickable((By.XPATH, next_button_xpath)))
    
                # Simuler un clic humain en déplaçant la souris sur le bouton
                actions = ActionChains(driver)
                actions.move_to_element(next_button).click().perform()
                
                # Attendre que les avis changent avant de continuer
                old_reviews = [el.text for el in driver.find_elements(By.XPATH, review_xpath)]
                wait.until(lambda d: [el.text for el in d.find_elements(By.XPATH, review_xpath)] != old_reviews)
                
                time.sleep(2)  # Pause pour assurer la stabilité
                page_number += 1
            except:
                print("Fin de la pagination.")
                break
    
    except Exception as e:
        print(f"Erreur lors de l'extraction: {e}")
    finally:
        driver.quit()
    
    # Enregistrer les avis dans un fichier Excel
    try:
        df = pd.DataFrame({"Avis": reviews})
        df.to_excel(output_file, index=False)
        print(f"Extraction terminée. Les avis sont enregistrés dans {output_file}.")
    except Exception as e:
        print(f"Erreur lors de l'enregistrement dans Excel: {e}") 

    Edit : On m'a dit d'essayer avec Pyppeteer. J'ai généré ce code, mais même problème. C'est toujours la page 1 qui charge alors que le script avance bien de page en page. 

    import asyncio
    from pyppeteer import launch
    import pandas as pd
    
    # Chemin de sortie pour le fichier Excel
    output_file = "/Users/marc/Desktop/Python/reviews.xlsx"
    
    async def scrape_reviews():
        # Lancer un navigateur en mode non-headless (visible)
        browser = await launch(
            headless=False,  # Mettre à False pour voir le navigateur
            args=[
                '--no-sandbox',
                '--disable-setuid-sandbox',
                '--disable-dev-shm-usage',
                '--window-size=1280,800',
                '--user-agent="Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36"'
            ]
        )
        page = await browser.newPage()
        await page.setViewport({'width': 1280, 'height': 800})
    
        # Naviguer vers la page des avis
        url = "https://www.hotelbreak.com/en/reviews"
        await page.goto(url, {"waitUntil": "networkidle2"})
    
        reviews = []
        page_number = 1
        max_pages = 3  # Limiter à 3 pages
    
        try:
            while page_number <= max_pages:
                print(f"Scraping page {page_number}...")
                
                # Attendre que les avis soient chargés
                await page.waitForXPath("//div[2]/div/div[1]/p", timeout=10000)
    
                # Extraire les avis
                review_elements = await page.xpath("//div[2]/div/div[1]/p")
                for element in review_elements:
                    review_text = await page.evaluate('(element) => element.textContent', element)
                    reviews.append({"Page": page_number, "Review": review_text})
    
                # Vérifier la présence du bouton "Next" et naviguer
                next_button = await page.xpath('//button[@aria-label="Go to next page" and not(@disabled)]')
                if next_button:
                    print("Next page button found, clicking to go to the next page...")
    
                    # Utiliser mouse.move() et mouse.click() pour simuler un clic humain
                    button = next_button[0]
                    button_box = await button.boundingBox()  # Obtenir la position du bouton
                    if button_box:
                        # Déplacer la souris vers le bouton
                        await page.mouse.move(button_box['x'] + button_box['width'] / 2, button_box['y'] + button_box['height'] / 2)
                        await asyncio.sleep(1)  # Petite pause avant de cliquer
                        await page.mouse.click(button_box['x'] + button_box['width'] / 2, button_box['y'] + button_box['height'] / 2)
                        await asyncio.sleep(5)  # Attendre que la page se charge après le clic
    
                        # Attendre un élément visible de la page pour s'assurer qu'on est bien sur la page suivante
                        try:
                            await page.waitForXPath("//div[2]/div/div[1]/p", timeout=15000)
                            page_number += 1
                            print(f"Successfully moved to page {page_number}.")
                        except asyncio.TimeoutError:
                            print("Timeout while waiting for content to load on the next page.")
                            break
                else:
                    print("No more pages to scrape.")
                    break
        finally:
            await browser.close()
    
        # Sauvegarder les avis dans un fichier Excel
        print("Saving reviews to Excel...")
        df = pd.DataFrame(reviews)
        df.to_excel(output_file, index=False)
        print(f"Scraping completed. File saved at {output_file}")
    
    # Lancer le script
    asyncio.run(scrape_reviews())
    



    -
    Edité par SC-Ven 2 janvier 2025 à 19:22:45

    • Partager sur Facebook
    • Partager sur Twitter
      3 janvier 2025 à 13:49:44

      SC-Ven a écrit:

      Le script va bien de page en page (je le vois via le navigateur en temps réel), mais c'est toujours le contenu de la page 1 qui s'affiche. 

      Le script simule un clic sur "page suivante". Ce qui ne change pas la page de commentaires affichée. Mais ça ne le fait pas non plus lorsque l'utilisateur clique dessus directement. 

      Par contre, cliquer sur le numéro de page à afficher fonctionne et sans pouvoir corriger le bug sur le site web...

      -
      Edité par mps 5 janvier 2025 à 22:51:17

      • Partager sur Facebook
      • Partager sur Twitter

      Scrapper des pages web en JS

      × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
      • Editeur
      • Markdown