CONNEXION
  • RetourJeux
    • Sorties
    • Hit Parade
    • Les + populaires
    • Les + attendus
    • Soluces
    • Tous les Jeux
    • Gaming
  • RetourActu Gaming
    • News
    • Astuces
    • Tests
    • Previews
    • Toute l'actu gaming
  • RetourBons plans
    • Bons plans
    • Bons plans Smartphone
    • Bons plans Hardware
    • Bons plans Image et Son
    • Bons plans Amazon
    • Bons plans Cdiscount
    • Bons plans Decathlon
    • Bons plans Fnac
    • Tous les Bons plans
  • RetourJVTech
    • Actus High-Tech
    • Intelligence Artificielle
    • Smartphones
    • Mobilité urbaine
    • Hardware
    • Image et son
    • Tutoriels
    • Tests produits High-Tech
    • Guides d'achat High-Tech
    • JVTech
  • RetourCulture
    • Actus Culture
    • Culture
  • RetourVidéos
    • A la une
    • Gaming Live
    • Vidéos Tests
    • Vidéos Previews
    • Gameplay
    • Trailers
    • Chroniques
    • Replay Web TV
    • Toutes les vidéos
  • RetourForums
    • Hardware PC
    • PS5
    • Switch 2
    • Xbox Series
    • Switch
    • Pokemon pocket
    • FC 25 Ultimate Team
    • League of Legends
    • Tous les Forums
  • PC
  • PS5
  • Xbox Series
  • Switch 2
  • PS4
  • One
  • Switch
  • iOS
  • Android
  • MMO
  • RPG
  • FPS
En ce moment Genshin Impact Valhalla Breath of the wild Animal Crossing GTA 5 Red dead 2
Liste des sujets

Aide scraping python forum Dealabs

Legendofblack
Legendofblack
Niveau 7
08 juin 2021 à 21:48:28

Bonjour.

Je viens demander de l'aide car je bute un peu sur ce projet.

Je débute dans le web scraping python.

J'ai réussi à mettre sur pieds un script fonctionnel pour La Centrale afin de lister les annonces pour un véhicule précis dans un tableau Excel avec les info de kilométrage, année du véhicule, tarif etc ...

J'ai ensuite voulu passer à la chose suivante :

Pour illustrer mon exemple voici cette page :

https://www.dealabs.com/discussions/un-ptit-coup-de-main-2163919

Je souhaiterai créer un script qui me liste tous les messages afin d'avoir une notif lorsqu'un nouveau message est posté.

Cependant lorsque j'utilise beautiful soup et que je fais un findall je n'ai qu'un seul message qui apparait au lieu des 10aines réellement existants.

Y a-t-il une quelconque protection ou quelque chose que j'ignore ?

Je peux fournir un bout de code si nécessaire.

Merci

Message édité le 08 juin 2021 à 21:49:07 par Legendofblack
blackapplex
blackapplex
Niveau 10
09 juin 2021 à 00:55:07

https://fr.wikipedia.org/wiki/PhantomJS

Azerban
Azerban
Niveau 16
09 juin 2021 à 08:59:53

Les commentaires sont chargés dynamiquement par le front Vue.js en interrogeant une API graphql. Tu peux interroger l'API mais il faut récupérer les bons cookies. Sinon tu peux employer selenium ou playwright avec Python pour lancer un navigateur et charger les commentaires. Voici comment faire en Python en mode headless (sans afficher le navigateur) :

# https://www.jeuxvideo.com/forums/42-47-66784467-1-0-1-0-aide-scraping-python-forum-dealabs.htm
# scraping_dealabs.py

from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.firefox.options import Options
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.ui import WebDriverWait

url = "https://www.dealabs.com/discussions/un-ptit-coup-de-main-2163919"

options = Options()
options.headless = True

driver = webdriver.Firefox(options=options)
driver.get(url)

# Accepter les cookies
button = WebDriverWait(driver, 2).until(
    EC.element_to_be_clickable((By.XPATH, "/html/body/main/div[4]/div[1]/div/div[1]/div[2]/button[2]/span"))
)
button.click()

# On recherche les commentaires et on affiche le texte
comments = driver.find_elements_by_class_name("commentList-item")
for comment in comments:
    print(comment.text)
    print('-' * 30)

driver.close()

N'oublie pas d'installer le package selenium et les bons drivers pour ton navigateur.

Azerban
Azerban
Niveau 16
09 juin 2021 à 09:27:41

Voici le script un peu plus résilient avec quelques variables supplémentaires (id du commentaire, auteur, contenu du commentaire, date) :

# https://www.jeuxvideo.com/forums/42-47-66784467-1-0-1-0-aide-scraping-python-forum-dealabs.htm
# scraping_dealabs.py

from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.firefox.options import Options
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.ui import WebDriverWait

url = "https://www.dealabs.com/discussions/un-ptit-coup-de-main-2163919"

options = Options()
options.headless = True

driver = webdriver.Firefox(options=options)
driver.get(url)

# Accepter les cookies
button = WebDriverWait(driver, 2).until(
    EC.element_to_be_clickable((By.XPATH, "/html/body/main/div[4]/div[1]/div/div[1]/div[2]/button[2]/span"))
)
button.click()

# On recherche les commentaires et on affiche le texte
comments_list = driver.find_element_by_class_name("commentList")
comments = comments_list.find_elements_by_class_name("commentList-item")

for comment in comments:
    _id = comment.get_attribute("id")
    author = comment.find_element_by_class_name('userInfo-username').text
    content = comment.find_element_by_class_name('userHtml-content').text
    timestamp = comment.find_element_by_class_name('text--color-greyShade').text
    print(_id)
    print(author)
    print(content)
    print(timestamp)
    print('-' * 30)

driver.close()
Legendofblack
Legendofblack
Niveau 7
10 juin 2021 à 16:52:48

Le 09 juin 2021 à 09:27:41 :
Voici le script un peu plus résilient avec quelques variables supplémentaires (id du commentaire, auteur, contenu du commentaire, date) :

# https://www.jeuxvideo.com/forums/42-47-66784467-1-0-1-0-aide-scraping-python-forum-dealabs.htm
# scraping_dealabs.py

from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.firefox.options import Options
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.ui import WebDriverWait

url = "https://www.dealabs.com/discussions/un-ptit-coup-de-main-2163919"

options = Options()
options.headless = True

driver = webdriver.Firefox(options=options)
driver.get(url)

# Accepter les cookies
button = WebDriverWait(driver, 2).until(
    EC.element_to_be_clickable((By.XPATH, "/html/body/main/div[4]/div[1]/div/div[1]/div[2]/button[2]/span"))
)
button.click()

# On recherche les commentaires et on affiche le texte
comments_list = driver.find_element_by_class_name("commentList")
comments = comments_list.find_elements_by_class_name("commentList-item")

for comment in comments:
    _id = comment.get_attribute("id")
    author = comment.find_element_by_class_name('userInfo-username').text
    content = comment.find_element_by_class_name('userHtml-content').text
    timestamp = comment.find_element_by_class_name('text--color-greyShade').text
    print(_id)
    print(author)
    print(content)
    print(timestamp)
    print('-' * 30)

driver.close()

Bonjour et merci pour ta réponse.

Je n'attendais pas un code tout fait mais bon on fera avec.

Concernant ta première remarque comment as tu déterminé que les commentaires sont chargés dynamiquement ?

Je pose des questions car je cherche à apprendre et surtout à comprendre.

Ensuite concernant ton code en lui même j'ai fait un essai mais j'ai quand même une apparition furtive de firefox est-ce normal ? Chrome est-t-il préférable ?

Aussi j'ai l'impression que selon la page du forum que je vais request, le fonctionnement n'est pas toujours parfait.

A titre informatif tu as pondu ce code en combien de temps ?

Tu es du métier ou c'est juste par passion que tu fais ça ?

Merci pour tes éventuelles réponses.

Message édité le 10 juin 2021 à 16:55:20 par Legendofblack
Azerban
Azerban
Niveau 16
10 juin 2021 à 19:21:35

Concernant ta première remarque comment as tu déterminé que les commentaires sont chargés dynamiquement ?

Il faut utiliser la console de développement de ton navigateur et aller dans la partie "réseau". Tu peux voir toutes les requêtes qui sont faites quand tu fais une requête (quand tu cliques sur un lien ou un bouton par exemple).

Dans les requêtes on voit des requêtes POST de type json qui retournent du graphql (successeur d'API Rest en gros). À partir de là tu sais que le front est généré dynamiquement par un framework frontend.

Je sais que c'est vue.js car j'ai un plugin vue.js installé dans mon navigateur (pour le développement) qui s'illumine quand il détecte du vue.js dans une page web.

Ensuite concernant ton code en lui même j'ai fait un essai mais j'ai quand même une apparition furtive de firefox est-ce normal ? Chrome est-t-il préférable ?

Hum curieux, peut être as-tu un vieux driver firefox ? Je ne sais pas trop... Je n'utilise pas chrome personnellement, je ne sais pas si ça change grand chose.

A titre informatif tu as pondu ce code en combien de temps ?

Environ 5-10 minutes (c'est la validation des cookies qui m'avait posé problème, je "cliquais" sur le bouton alors qu'il n'était pas encore apparu, il fallait juste appeler la fonction element_to_be_clickable pour ne pas cliquer trop tôt avec un délai de 2 secondes).

Message édité le 10 juin 2021 à 19:25:50 par Azerban
Pseudo supprimé
Pseudo supprimé 18 juin 2021 à 02:27:13

Est ce que tous tes messages apparaissent bien dans le contenu de ton parseur ?

Azerban
Azerban
Niveau 16
18 juin 2021 à 14:53:45

Le 18 juin 2021 à 02:27:13 :
Est ce que tous tes messages apparaissent bien dans le contenu de ton parseur ?

Non le parser ne parse que la première page. Pour scraper les pages suivantes, il faut cliquer sur le bouton "Page suivante". Déjà il faut s'assurer de sa présence (si une seule page bouton absent). Ensuite il faut vérifier qu'il est cliquable (sinon ça veut dire qu'on est à la dernière page). On met tout ça dans une boucle infinie et c'est dans la poche :ok:

Un test avec cette page : https://www.dealabs.com/bons-plans/saneo-climatiseur-2166879

https://image.noelshack.com/fichiers/2021/24/5/1624020641-dealabs-website.png https://image.noelshack.com/fichiers/2021/24/5/1624020647-dealabs-scraper.png

_lucco_
_lucco_
Niveau 10
18 juin 2021 à 15:00:08

J'approuve l'utilisation de selenium :oui:

Azerban
Azerban
Niveau 16
18 juin 2021 à 15:53:29

5484 commentaire pour un forfait téléphonique : https://www.dealabs.com/bons-plans/nouveaux-clients-forfait-mobile-sosh-appelssmsmms-illimites-20go-data-8go-en-eudom-sans-conditions-de-duree-ni-engagement-2165042 https://image.noelshack.com/fichiers/2018/29/6/1532128784-risitas33.png

J'aurais dû enregistrer le tout dans un fichier https://image.noelshack.com/fichiers/2021/24/5/1624024270-dealabs-forfait-telephonique.png
https://image.noelshack.com/fichiers/2018/27/4/1530827992-jesusreup.png

Legendofblack
Legendofblack
Niveau 7
25 juin 2021 à 22:18:46

Le 18 juin 2021 à 15:53:29 :
5484 commentaire pour un forfait téléphonique : https://www.dealabs.com/bons-plans/nouveaux-clients-forfait-mobile-sosh-appelssmsmms-illimites-20go-data-8go-en-eudom-sans-conditions-de-duree-ni-engagement-2165042 https://image.noelshack.com/fichiers/2018/29/6/1532128784-risitas33.png

J'aurais dû enregistrer le tout dans un fichier https://image.noelshack.com/fichiers/2021/24/5/1624024270-dealabs-forfait-telephonique.png
https://image.noelshack.com/fichiers/2018/27/4/1530827992-jesusreup.png

Bonsoir et merci pour ta réponse très détaillée.

Cependant en prenant ta page en exemple celle du climatiseur.

Les seuls commentaires que le script me retourne sont les top commentaires en entête, pas les autres.

Est ce que le fait que j'utilise des addons dans Chrome peut être le problème ?

J'avoue ne pas comprendre totalement le pourquoi du comment.

Merci

Azerban
Azerban
Niveau 16
26 juin 2021 à 21:20:50

Non rien à voir avec Chrome.

C'est parce que la section "Top commentaires" est dans une div qui possède l'attribut de classe "commentList". Comme je recherchais le premier élément, je ne scrapais que ceux de la rubrique "top commentaires" quand celle-ci était présente.

J'ai réécrit le script et maintenant je scrape tous les commentaires.

JohnDoe80
JohnDoe80
Niveau 1
21 août 2021 à 01:25:52

Le 26 juin 2021 à 21:20:50 :
Non rien à voir avec Chrome.

C'est parce que la section "Top commentaires" est dans une div qui possède l'attribut de classe "commentList". Comme je recherchais le premier élément, je ne scrapais que ceux de la rubrique "top commentaires" quand celle-ci était présente.

J'ai réécrit le script et maintenant je scrape tous les commentaires.

Bonsoir, est il possible de modifier le script afin qu'il récupère aussi un éventuel lien complet svp, car actuellement, il prends simplement le texte brut? Et si possible uniquement le dernier commentaire aussi? Savez vous comment faire svp?
Actuellement, lorsqu'il y a un lien sur le post, il le récupère comme ceci:

comment-xxxxxxxx
Pseudo
Commentaire
amazon.fr/dp/…DD/

il y a 2 h et 28 min
Merci!

Message édité le 21 août 2021 à 01:26:26 par JohnDoe80
Azerban
Azerban
Niveau 16
29 août 2021 à 20:12:48

Bonsoir, est il possible de modifier le script afin qu'il récupère aussi un éventuel lien complet svp, car actuellement, il prends simplement le texte brut? Et si possible uniquement le dernier commentaire aussi? Savez vous comment faire svp?

Bonjour,

Qu'entends-tu par lien complet ? C'est le lien complet vers le commentaire ? C'est assez facile à faire en Python car on voit que l'url vers un commentaire précis est construite en concaténant l'url de l'article et l'ID du commentaire (avec un # au milieu).

Exemple :

https://www.dealabs.com/bons-plans/saneo-climatiseur-2166879#comment-33904248

Comme le script renvoie l'ID du commentaire et que nous avons le lien du produit dans la variable url, il suffit de concaténer les deux et mettre la nouvelle variable dans la boucle (variable comment_url) :

for comment in comments:
    _id = comment.get_attribute("id")
    author = comment.find_element_by_class_name('userInfo-username').text
    content = comment.find_element_by_class_name('userHtml-content').text
    timestamp = comment.find_element_by_class_name('text--color-greyShade').text
    comment_url = f"{url}#{_id}"

    print(_id)
    print(author)
    print(content)
    print(timestamp)
    print(comment_url)
    print('-' * 30)

Pour renvoyer le dernier commentaire, il suffit simplement de mettre une variable last_comment dans la boucle qui est égale à la valeur de comment. À chaque tour de boucle, la valeur changera pour le dernier commentaire scrapé (les commentaires sont scrapés par ordre d'apparition sur les pages, donc le dernier commentaire scrapé sera le dernier commentaire posté).

Dans la boucle, vous pouvez mettre un truc du genre :

last_comment = {
    "author": author,
    "product_url": url,
    "timestamp": timestamp,
    "content": content,
    "comment_url": comment_url,
    "comment_id":_id,
}

Le mieux serait d'écrire une méthode qui va directement à la dernière page et qui scrape cette page plutôt que de scraper tous les commentaires pour toutes les pages pour avoir le dernier. J'implémenterai peut être ça plus tard dans mon code.

Azerban
Azerban
Niveau 16
29 août 2021 à 20:14:42

D'ailleurs si vous avez des difficultés, vous pouvez poser vos questions ici, pas besoin d'aller copier/coller mon code sur stackoverflow https://stackoverflow.com/questions/68143333/web-scraping-issue-with-selenium-get-comments :-)))

JohnDoe80
JohnDoe80
Niveau 1
30 août 2021 à 22:58:59

Le 29 août 2021 à 20:14:42 :
D'ailleurs si vous avez des difficultés, vous pouvez poser vos questions ici, pas besoin d'aller copier/coller mon code sur stackoverflow https://stackoverflow.com/questions/68143333/web-scraping-issue-with-selenium-get-comments :-)))

Merci Azerban pour toutes ces précisions! Au top!
Alors pour le morceau de code qui récupère le lien commentaire, c'est impec, ça fonctionne bien!
Mon problème viens pour la deuxième partie que tu as posté au dessus, pour le dernier commentaire. Je n'arrive pas a l'inclure dans le code (Désolé pour mon ignorance, je ne maitrise que très peu).
Voici comment je l'ai inclus:


for comment in comments:
    _id = comment.get_attribute("id")
    author = comment.find_element_by_class_name('userInfo-username').text
    content = comment.find_element_by_class_name('userHtml-content').text
    timestamp = comment.find_element_by_class_name('text--color-greyShade').text
    link = comment.get_attribute('href')
    comment_url = f"{url}#{_id}"
    last_comment = {
        "author": author,
        "product_url": url,
        "timestamp": timestamp,
        "content": content,
        "comment_url": comment_url,
        "comment_id":_id,
    }

Est-ce correct?
Dernier point, lorsque je parlais de l'url, ce n'était pas réellement le lien commentaire, mais plutôt un éventuel lien qui serait dans le commentaire. Lorsque le script se lance, le lien est récupéré sous la forme "amazon.fr/dp/…DD/", donc incomplet. Serait il possible de récuperer l'url complète?
Merci pour le temps accordé.

Message édité le 30 août 2021 à 23:00:14 par JohnDoe80
Sous forums
  • Aide à l'achat Mac
  • Création de sites web
  • Internet
  • Macintosh
  • Création de Jeux
  • Linux
  • Programmation
  • Steam Deck
  • Hardware
La vidéo du moment