Linux Ubuntu Xfce
Web scraping avec Python Python Crawling & Scraping-Practical Development Guide for Data Collection and Analysis Pratiquez Selenium WebDriver
Chrome
sudo curl -sS -o - https://dl-ssl.google.com/linux/linux_signing_key.pub | apt-key add
sudo echo "deb [arch=amd64] http://dl.google.com/linux/chrome/deb/ stable main" >> /etc/apt/sources.list.d/google-chrome.list
sudo apt-get -y update
sudo apt-get -y install google-chrome-stable
Autre
sudo apt install chromium-chromedriver liblzma-dev \
&& pip install bs4 selenium pandas
Diverses méthodes sont préparées pour bs4, et si vous utilisez pleinement ces méthodes et expressions régulières (re), ** rien ne peut être obtenu **
Le plus rapide et peut utiliser le plus de sélecteurs CSS
html_doc = '<html>...</html>'
soup = BeautifulSoup(html_doc, 'lxml')
Si vous ne le faites pas, l'épave du processus s'accumulera.
from selenium import webdriver
driver = webdriver.Chrome()
#Mettre fin au pilote
driver.close()
driver.quit()
Une fois la livraison terminée, recherchez un trésor avec BS4
options = ChromeOptions()
options.add_argument('--headless') #Mode sans fenêtre
driver = Chrome(options=options)
url = 'https://www.example.com/'
driver.get(url)
#Démarrer le fonctionnement de Selenium
...
...
...
#Fin de l'opération Selenium
html = driver.page_source.encode('utf-8')
soup = BeautifulSoup(html, "lxml")
#Le traitement BS4 a commencé
...
...
...
#Traitement BS4 terminé
Recherche par nom de balise directement depuis l'objet BeautifulSoup
Quand il y a peu de balises comme celle-ci
from bs4 import BeautifulSoup
html_doc = '''
<html>
<head>
<title>hello soup</title>
</head>
<body>
<p class="my-story">my story</p>
</body>
</html>
'''
soup = BeautifulSoup(html_doc, 'lxml')
print(soup.title)
print(soup.title.text)
print(soup.p)
print(soup.p['class'])
print(soup.p.text)
Résultat d'exécution
<title>hello soup</title>
hello soup
<p class="my-story">my story</p>
['my-story']
my story
BeautfulSoup a 4 types d'objets: Tag
, NavigableString
, BeautifulSoup
, Comment
.
Parmi ceux-ci, ceux que j'utilise souvent sont «Beautiful Soup» et «Tag».
BeautifulSoup
: convertit la source HTML en un format (arborescence) qui peut être géré par Python
Tag
: Un objet Tag est créé lorsqu'une méthode spécifique est utilisée pour un objet BeautifulSoup.
Vous pouvez rechercher n'importe quoi en utilisant les méthodes find
et find_all
sur un objet BeautifulSoup
, mais vous devez savoir ce que la méthode produit pour faire une bonne recherche.
** Objets créés par la méthode **
find
→ bs4.element.Tag
find_all
→ bs4.element.ResultSet
** Valeur renvoyée lorsque rien n'est trouvé **
find
→ None
find_all
→ [] liste vide
bs4.element.Tag
Vous pouvez penser qu'il est généré en utilisant des méthodes bs4 autres que la méthode find_all
, la méthode BeautifulSoup
, la méthode select
.
from bs4 import BeautifulSoup
html_doc = '''
<html>
<head>
<title>hello soup</title>
</head>
<body>
<p class="my-story">my story</p>
<a class='brother' href='http://example.com/1' id='link1'>Lien 1</a>
<a class='brother' href='http://example.com/2' id='link2'>Lien 2</a>
<a class='brother' href='http://example.com/3' id='link3'>Lien 3</a>
</body>
</html>
'''
soup = BeautifulSoup(html_doc, 'lxml')
print('tag1')
tag1 = soup.find('a')
print(tag1)
print(type(tag1))
print('tag2')
tag2 = soup.a
print(tag2)
print(type(tag2))
bs4.element.ResultSet
Généré en utilisant les méthodes find_all
, BeautifulSoup
et select
Une image avec beaucoup de bs4.element.Tag
dans la liste (** Cette image est assez importante **)
python:bs4.element.ResultSet image
bs4.element.ResultSet = [bs4.element.Tag, bs4.element.Tag, bs4.element.Tag,...]
Par conséquent, il ne peut pas être recherché tel quel, et il est utilisé après l'avoir supprimé de la liste.
Si vous le retirez, vous pouvez utiliser la même méthode que bs4.element.tag
ci-dessus.
- La méthode ne peut pas être utilisée! C'est presque quand vous essayez d'utiliser la méthode
bs4.element.Tag
pourbs4.element.ResultSet
.
from bs4 import BeautifulSoup
html_doc = '''
<html>
<head>
<title>hello soup</title>
</head>
<body>
<p class="my-story">my story</p>
<a class='brother' href='http://example.com/1' id='link1'>Lien 1</a>
<a class='brother' href='http://example.com/2' id='link2'>Lien 2</a>
<a class='brother' href='http://example.com/3' id='link3'>Lien 3</a>
</body>
</html>
'''
soup = BeautifulSoup(html_doc, 'lxml')
print('tag3')
tag3 = soup.select('a:nth-of-type(2)') #Rechercher par la présence ou l'absence du tag a dans le body tag
print(tag3)
print(type(tag3))
print('tag4')
tag4 = soup.select('.link1') #Classe de sélecteur CSS
print(tag4)
print(type(tag4))
print('tag5')
tag5 = soup.select('a[href]') #Rechercher des balises avec ou sans attributs
print(tag5)
print(type(tag5))
Si vous conservez la valeur par défaut, lorsque vous essayez d'imprimer un gros fichier, vous obtiendrez une erreur «Débit de données IO Pub dépassé», alors changez-le en illimité
Créer un fichier de configuration
jupyter notebook --generate-config
python:~/.jupyter/jupyter_notebook_config.py
#Avant changement 1000000 → Après changement 1e10
jupyter notebook --NotebookApp.iopub_data_rate_limit=1e10
Rapide car il lit et écrit au format binaire ('b' dans le code signifie binaire)
Il existe une bibliothèque avec la même fonction, joblib
, mais c'est bon à utiliser lorsque vous voulez réduire la taille du fichier au détriment de la vitesse.
l'écriture(dump)
import pickle
example = 'example'
with open('example.pickle', 'wb') as f:
pickle.dump(example, f)
Lis(load)
with open('example.pickle', 'rb') as f:
example = pickle.load(f)
Lorsque vous essayez d'écrire un objet bs4
(bs4.BeautifulSoup, etc.) Puisque l'erreur "profondeur de récursivité maximale dépassée lors du décapage d'un objet
" apparaît, convertissez-la en "chaîne", etc. avant de l'enregistrer.
dump
import pickle
example = 'example'
with open('example.pickle', 'wb') as f:
pickle.dump(str(example), f)
load
with open('example.pickle', 'rb') as f:
example = BeatitfulSoup(pickle.load(f), 'lxml')
Si vous venez de le lire, il ne peut pas être géré par bs4 car il s'agit d'un type str
.
Par conséquent, convertissez en type bs4
lors de la lecture
** Si la méthode ci-dessus ne fonctionne pas **
Si vous ne pouvez pas vider dict
Dans un tel cas, il est bon de vider avec json
dump
import json
with open('example.json', 'w') as f:
json.dump(example, f)
load
with open('example.json', 'r') as f:
json.load(f)
Jupyter Notebook
Lorsque vous regardez le DataFrame des pandas, si la largeur de cellule est la valeur par défaut, les caractères seront coupés, alors réglez la largeur de cellule au maximum
css:~/.jupyter/custom/custom.css
.container { width:100% !important; }
Utilisez % time
qui ne peut être utilisé que dans l'environnement Jupyter
Ceci est une méthode intégrée de Jupyter
, donc aucune importation n'est requise
Comment utiliser
%time example_function()
Lorsque vous voulez obtenir le scraping
de https: // www.example.com / topics / scraping
Spécifiez /
avec split
pour obtenir l'élément derrière
code
url = 'https://www.example.com/topics/scraping'
print(url.split('/'))
#['https:', '', 'www.example.com', 'topics', 'scraping']
print(url.split('/')[-1])
#scraping
Pandas
Pandas UserWarning: Could not import the lzma module. Your installed Python is incomplete
Erreur lors de l'absence de packages requis pour les pandas
sudo apt install liblzma-dev
import pandas as pd
df = pd.DataFrame(index=[1,2,3], {'Column1':data1, 'Column2':'data2', 'Column3':'data3'})
#Extraire Column3 et en faire une liste
col3 = pd.Series(df['Column3']).tolist()
La valeur par défaut est justifiée à droite, il est donc difficile de lire les URL et l'anglais.
df.style.set_properties(**{'text-align': 'left'}) #Justifié à gauche
Recommended Posts