Skip to content

Commit 25046de

Browse files
linogalianagithub-actions[bot]antoine-palazz
authored
Rectifie bug TP webscraping (#281)
* affiche image * Automated changes * Automated changes * dcompose * Update find_element functions (#267) Update find_elements as the function changed with a recent Selenium update * reformat * eval false * eval false * Automated changes * Automated changes Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com> Co-authored-by: Antoine Palazzolo <97433407+antoine-palazz@users.noreply.github.com>
1 parent d068cb6 commit 25046de

File tree

1 file changed

+110
-49
lines changed
  • content/course/manipulation/04a_webscraping_TP

1 file changed

+110
-49
lines changed

content/course/manipulation/04a_webscraping_TP/index.qmd

Lines changed: 110 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -766,11 +766,17 @@ celui qui suit
766766

767767
{{% box status="exercise" title="Exercice" icon="fas fa-pencil-alt" %}}
768768

769-
Pour cet exercice, nous vous demandons d'obtenir différentes informations sur les pokémons à partir du site internet [pokemondb.net](http://pokemondb.net/pokedex/national).
769+
Pour cet exercice,
770+
nous vous demandons d'obtenir différentes informations sur les pokémons
771+
à partir du site internet [pokemondb.net](http://pokemondb.net/pokedex/national).
770772

771773
## Etape 1
772774

773-
Nous souhaitons tout d'abord obtenir les informations personnelles des ``893`` pokemons sur [pokemondb.net](http://pokemondb.net/pokedex/national). Les informations que nous aimerions obtenir au final pour les pokemons sont celles contenues dans 4 tableaux :
775+
Nous souhaitons tout d'abord obtenir les
776+
informations personnelles de tous
777+
les pokemons sur [pokemondb.net](http://pokemondb.net/pokedex/national).
778+
779+
Les informations que nous aimerions obtenir au final pour les pokemons sont celles contenues dans 4 tableaux :
774780

775781
- Pokédex data
776782
- Training
@@ -919,7 +925,7 @@ Nous aimerions que vous récupériez également les images des 5 premiers pokém
919925

920926
Idée : Utilisez les modules `request` et [`shutil`](https://docs.python.org/3/library/shutil.html)
921927

922-
_pour cette question, il faut que vous cherchiez de vous même certains éléments, tout n'est pas présent dans le TD_.
928+
:warning: _Pour cette question, il faut que vous cherchiez de vous même certains éléments, tout n'est pas présent dans le TD_.
923929

924930
```{python}
925931
#| include: false
@@ -950,7 +956,12 @@ for indice_pokemon in range(0,nb_pokemons) :
950956
```{python}
951957
#| echo: false
952958
#plt.savefig('pokemon.png', bbox_inches='tight')
953-
plt.show()
959+
ax[0].get_figure()
960+
```
961+
962+
```{python}
963+
#| include: false
964+
shutil.copyfile("bulbasaur.jpg", "featured.jpg")
954965
```
955966

956967
{{% /box %}}
@@ -972,43 +983,80 @@ sur <a href="https://github.com/linogaliana/python-datascientist" class="github"
972983
# `Selenium` : mimer le comportement d'un utilisateur internet
973984

974985

975-
Jusqu'à présent, nous avons raisonné comme si nous connaissions toujours l'url qui nous intéresse. De plus, les pages que nous visitons sont "statiques", elles ne dépendent pas d'une action ou d'une recherche de l'internaute.
986+
Jusqu'à présent,
987+
nous avons raisonné comme si nous connaissions toujours l'url qui nous intéresse.
988+
De plus, les pages que nous visitons sont "statiques",
989+
elles ne dépendent pas d'une action ou d'une recherche de l'internaute.
990+
991+
Nous allons voir à présent comment nous en sortir pour remplir
992+
des champs sur un site web et récupérer ce qui nous intéresse.
993+
La réaction d'un site _web_ à l'action d'un utilisateur passe régulièrement par
994+
l'usage de `JavaScript` dans le monde du développement _web_.
995+
Le package [Selenium](https://pypi.python.org/pypi/selenium) permet
996+
de reproduire, depuis un code automatisé, le comportement
997+
manuel d'un utilisateur. Il permet ainsi
998+
d'obtenir des informations du site qui ne sont pas dans le
999+
code `HTML` mais qui apparaissent uniquement à la suite de
1000+
l'exécution de script `JavaScript` en arrière plan.
9761001

977-
Nous allons voir à présent comment nous en sortir pour remplir des champs sur un site web et récupérer ce qui nous intéresse.
1002+
`Selenium` se comporte comme un utilisateur lambda sur internet :
1003+
il clique sur des liens, il remplit des formulaires, etc.
9781004

979-
L'avantage du package [Selenium](https://pypi.python.org/pypi/selenium) est d'obtenir des informations du site qui ne sont pas dans le code html mais qui apparaissent uniquement à la suite de l'exécution de script javascript en arrière plan.
1005+
## Premier exemple en scrapant un moteur de recherche
9801006

981-
Selenium se comporte comme un utilisateur lambda sur internet : il clique sur des liens, il remplit des formulaires etc. Dans cet exemple, nous allons essayer de aller sur le site de [Bing Actualités](https://www.bing.com/news) et entrer dans la barre de recherche un sujet donné (Trump).
1007+
Dans cet exemple, nous allons essayer de aller sur le
1008+
site de [Bing Actualités](https://www.bing.com/news) et entrer dans la barre de recherche un sujet donné (__"Trump"__).
9821009

983-
L'installation de `selenium` nécessite d'avoir chromium qui est un
1010+
L'installation de `Selenium` nécessite d'avoir `Chromium` qui est un
9841011
navigateur Google Chrome minimaliste.
985-
La version de [chromedriver](https://sites.google.com/a/chromium.org/chromedriver/) doit être ``>= 2.36`` et dépend de la version de Chrome que vous avez sur votre poste.
1012+
La version de [chromedriver](https://sites.google.com/a/chromium.org/chromedriver/)
1013+
doit être `>= 2.36` et dépend de la version de `Chrome` que vous avez sur votre environnement
1014+
de travail. Pour installer cette version minimaliste de `Chrome` sur un environnement
1015+
`Linux`, vous pouvez
1016+
vous référer à l'encadré dédié
9861017

987-
~~~python
988-
!pip install selenium
1018+
{{% box status="note" title="Note" icon="fa fa-comment" %}}
9891019

990-
# Sur votre poste
991-
# télécharger le chrome driver https://chromedriver.storage.googleapis.com/index.html?path=85.0.4183.83/
1020+
L'installation nécessite de passer par le terminal.
1021+
D'abord, il convient d'installer les dépendances.
1022+
Sur `Colab`, vous pouvez utiliser les commandes suivantes:
9921023

993-
# Sur google colab
994-
# https://stackoverflow.com/questions/51046454/how-can-we-use-selenium-webdriver-in-colab-research-google-com
995-
!apt-get update # to update ubuntu to correctly run apt install
996-
!apt install chromium-chromedriver
1024+
```{python}
1025+
#| eval: false
1026+
!sudo apt get update
1027+
!sudo apt install -y unzip xvfb libxi6 libgconf-2-4 -y
1028+
!sudo apt install chromium-chromedriver -y
9971029
!cp /usr/lib/chromium-browser/chromedriver /usr/bin
1030+
```
1031+
1032+
Si vous êtes dans un `Jupyter Notebook`, vous pouvez
1033+
exécuter les commandes ci-dessous en les faisant
1034+
précéder de `!`
1035+
1036+
Vous pouvez ensuite installer `Selenium`. Par
1037+
exemple, depuis une
1038+
cellule de `Notebook`:
1039+
1040+
```{python}
1041+
#| eval: false
1042+
!pip install selenium
1043+
```
1044+
{{% /box %}}
1045+
1046+
```{python}
1047+
#| eval: false
9981048
import sys
9991049
sys.path.insert(0,'/usr/lib/chromium-browser/chromedriver')
1000-
~~~
1001-
1002-
~~~python
10031050
import selenium
10041051
path_to_web_driver = "chromedriver"
1005-
~~~
1006-
1007-
On va sur le site de Bing Actualités, et on lui indique le mot clé que nous souhaitons chercher.
1052+
```
10081053

1009-
Dans cet exemple, on va voir que l'ordinateur va ouvrir une nouvelle fenêtre.
1054+
En premier lieu, il convient d'initialiser le comportement
1055+
de Selenium en répliquant les paramètres
1056+
du navigateur:
10101057

1011-
~~~python
1058+
```{python}
1059+
#| eval: false
10121060
import time
10131061
10141062
from selenium import webdriver
@@ -1022,45 +1070,53 @@ chrome_options.add_argument('--no-sandbox')
10221070
10231071
browser = webdriver.Chrome(executable_path=path_to_web_driver,
10241072
options=chrome_options)
1073+
```
10251074

1075+
On va sur le site de `Bing Actualités`, et on lui indique le mot clé que nous souhaitons chercher.
1076+
1077+
```{python}
1078+
#| eval: false
10261079
browser.get('https://www.bing.com/news')
10271080
10281081
# on cherche l'endroit où on peut remplir un formulaire
10291082
# en utilisant les outils du navigateur > inspecter les éléments de la page
10301083
# on voit que la barre de recherche est un élement du code appelé 'q' comme query
10311084
# on lui demande de chercher cet élément
10321085
1033-
search = browser.find_element_by_name('q')
1086+
search = browser.find_element("name", "q")
10341087
print(search)
10351088
print([search.text, search.tag_name, search.id])
10361089
10371090
# on envoie à cet endroit le mot qu'on aurait tapé dans la barre de recherche
10381091
search.send_keys("Trump")
10391092
1040-
search_button = browser.find_element_by_xpath("//input[@id='sb_form_go']")
1093+
search_button = browser.find_element("xpath", "//input[@id='sb_form_go']")
10411094
1042-
#search_button = browser.find_element_by_id('search_button_homepage')
1095+
#search_button = browser.find_element("id", 'search_button_homepage')
10431096
10441097
search_button.click()
10451098
10461099
# on appuie sur le bouton "Entrée" Return en anglais
10471100
#search.send_keys(Keys.RETURN)
1048-
~~~
1101+
```
10491102

1050-
~~~python
1103+
```{python}
1104+
#| eval: false
10511105
png = browser.get_screenshot_as_png()
1052-
~~~
1106+
```
10531107

1054-
~~~python
1108+
```{python}
1109+
#| eval: false
10551110
from IPython.display import Image
10561111
Image(png, width='500')
1057-
~~~
1112+
```
10581113

10591114
On extrait les résultats.
10601115

1061-
~~~python
1116+
```{python}
1117+
#| eval: false
10621118
from selenium.common.exceptions import StaleElementReferenceException
1063-
links = browser.find_elements_by_xpath("//div/a[@class='title'][@href]")
1119+
links = browser.find_elements("xpath", "//div/a[@class='title'][@href]")
10641120
10651121
results = []
10661122
for link in links:
@@ -1072,25 +1128,30 @@ for link in links:
10721128
results.append(url)
10731129
10741130
len(results)
1075-
~~~
1131+
```
10761132

1077-
~~~python
1133+
```{python}
1134+
#| eval: false
10781135
# on a une pause de 10 secondes pour aller voir ce qui se passe sur la page internet
10791136
# on demande de quitter le navigateur quand tout est fini
10801137
browser.quit()
1081-
~~~
1138+
```
10821139

1083-
~~~python
1140+
```{python}
1141+
#| eval: false
10841142
print(results)
1085-
~~~
1143+
```
10861144

10871145
## Utiliser selenium pour jouer à 2048
10881146

1089-
Dans cet exemple, on utilise le module pour que python appuie lui même sur les touches du clavier afin de jouer à 2048.
1147+
Dans cet exemple, on utilise le module pour que `Python`
1148+
appuie lui même sur les touches du clavier afin de jouer à 2048.
10901149

1091-
Note : ce bout de code ne donne pas une solution à 2048, il permet juste de voir ce qu'on peut faire avec selenium
1150+
Note : ce bout de code ne donne pas une solution à 2048,
1151+
il permet juste de voir ce qu'on peut faire avec `Selenium`
10921152

1093-
~~~python
1153+
```{python}
1154+
#| eval: false
10941155
from selenium import webdriver
10951156
from selenium.webdriver.common.keys import Keys
10961157
@@ -1103,17 +1164,17 @@ browser.get('https://play2048.co//')
11031164
# Ce qu'on va faire : une boucle qui répète inlassablement la même chose : haut / droite / bas / gauche
11041165
11051166
# on commence par cliquer sur la page pour que les touches sachent
1106-
browser.find_element_by_class_name('grid-container').click()
1107-
grid = browser.find_element_by_tag_name('body')
1167+
browser.find_element("class name", 'grid-container').click()
1168+
grid = browser.find_element("tag name", 'body')
11081169
11091170
# pour savoir quels coups faire à quel moment, on crée un dictionnaire
11101171
direction = {0: Keys.UP, 1: Keys.RIGHT, 2: Keys.DOWN, 3: Keys.LEFT}
11111172
count = 0
11121173
11131174
while True:
11141175
try: # on vérifie que le bouton "Try again" n'est pas là - sinon ça veut dire que le jeu est fini
1115-
retryButton = browser.find_element_by_link_text('Try again')
1116-
scoreElem = browser.find_element_by_class_name('score-container')
1176+
retryButton = browser.find_element("link text",'Try again')
1177+
scoreElem = browser.find_element("class name", 'score-container')
11171178
break
11181179
except:
11191180
#Do nothing. Game is not over yet
@@ -1125,4 +1186,4 @@ while True:
11251186
11261187
print('Score final : {} en {} coups'.format(scoreElem.text, count))
11271188
browser.quit()
1128-
~~~
1189+
```

0 commit comments

Comments
 (0)