Comment gratter un site web javascript en Python?
J'essaye de gratter un site Web. J'ai essayé d'utiliser deux méthodes, mais les deux ne me fournissent pas le code source complet du site Web que je recherche. J'essaie de récupérer les titres des actualités à partir de l'URL du site Web fournie ci-dessous.
URL: "https://www.todayonline.com/"
Ce sont les deux méthodes que j'ai essayées mais qui ont échoué.
Méthode 1: Belle soupe
tdy_url = "https://www.todayonline.com/"
page = requests.get(tdy_url).text
soup = BeautifulSoup(page)
soup # Returns me a HTML with javascript text
soup.find_all('h3')
### Returns me empty list []
Méthode 2: Sélénium + BeautifulSoup
tdy_url = "https://www.todayonline.com/"
options = Options()
options.headless = True
driver = webdriver.Chrome("chromedriver",options=options)
driver.get(tdy_url)
time.sleep(10)
html = driver.page_source
soup = BeautifulSoup(html)
soup.find_all('h3')
### Returns me only less than 1/4 of the 'h3' tags found in the original page source
Veuillez aider. J'ai essayé de gratter d'autres sites Web d'informations et c'est tellement plus facile. Je vous remercie.
Réponses
Vous pouvez accéder aux données via l'API (consultez l'onglet Réseau):
Par exemple,
import requests
url = "https://www.todayonline.com/api/v3/news_feed/7"
data = requests.get(url).json()
Il existe différentes manières de rassembler le contenu d'une page Web contenant du Javascript.
- Utilisation
seleniumavec le pilote Web Firefox - Utilisation d'un navigateur sans tête avec
phantomJS - Effectuer un appel d'API à l'aide d'un client REST ou d'une
requestsbibliothèque python
Vous devez d'abord faire vos recherches
Je vais vous suggérer l'approche assez simple,
import requests
from bs4 import BeautifulSoup as bs
page = requests.get('https://www.todayonline.com/googlenews.xml').content
soup = bs(page)
news = [i.text for i in soup.find_all('news:title')]
print(news)
production
['DBS named world’s best bank by New York-based financial publication',
'Russia has very serious questions to answer on Navalny - UK',
"Exclusive: 90% of China's Sinovac employees, families took coronavirus vaccine - CEO",
'Three militants killed after fatal attack on policeman in Tunisia',
.....]
Vous pouvez également consulter la page XML pour plus d'informations si nécessaire.
PS Vérifiez toujours la conformité avant de supprimer un site Web :)
Les données d'actualités sur le site Web que vous essayez de récupérer sont extraites du serveur à l'aide de JavaScript (cela s'appelle XHR - XMLHttpRequest ). Cela se produit de manière dynamique, pendant le chargement ou le défilement de la page. donc ces données ne sont pas renvoyées à l'intérieur de la page renvoyée par le serveur.
Dans le premier exemple, vous n'obtenez que la page renvoyée par le serveur - sans les nouvelles, mais avec JS qui est censé les obtenir. Ni les requêtes ni BeautifulSoup ne peuvent exécuter JS.
Cependant, vous pouvez essayer de reproduire les requêtes qui obtiennent des titres d'actualité du serveur avec des requêtes Python. Suivez les étapes suivantes:
- Ouvrez DevTools de votre navigateur (vous devez généralement appuyer sur F12ou Ctrl+ Shit+ Ipour cela) et jetez un œil aux demandes qui reçoivent des titres d'actualités du serveur. Parfois, c'est encore plus facile que le web scraping avec BeautifulSoup. Voici une capture d'écran (Firefox):
Copiez le lien de la demande (clic droit -> Copier -> Copier le lien) et transmettez-le à
requests.get(...).Obtenez
.json()de la demande. Il renverra un dict avec lequel il est facile de travailler. Pour mieux comprendre la structure du dict, je recommanderais de l'utiliserpprintau lieu d'une simple impression. Notez que vous devez fairefrom pprint import pprintavant de l'utiliser.
Voici un exemple de code qui récupère les titres de l'actualité principale de la page:
import requests
nodes = requests.get("https://www.todayonline.com/api/v3/news_feed/7")\
.json()["nodes"]
for node in nodes:
print(node["node"]["title"])
Si vous voulez gratter un groupe d'actualités sous légende, vous devez modifier le numéro après news_feed/dans l'URL de la requête (pour l'obtenir, il vous suffit de filtrer les requêtes par "news_feed" dans les DevTools et de faire défiler la page d'actualités vers le bas).
Parfois, les sites Web sont protégés contre les bots (bien que le site Web que vous essayez de supprimer ne le soit pas). Dans de tels cas, vous devrez peut-être également suivre ces étapes .