3
votes

beautifulsoup4 ne renvoie pas de contenu

Bonjour , j'ai suivi et compris cet article sur la façon de lire le contenu des sites et cela a parfaitement fonctionné: geeksforgeeks.org: lecture du contenu de la page Web sélectionnée à l'aide de Python Web Scraping

Mais quand j'ai changé mon code pour travailler avec un autre site, il ne renvoie aucune valeur. J'essaie d'obtenir ces Value1 et Value2, etc. comme indiqué ci-dessous.

Remarque: il est légal de lire le contenu de cette page Web.

<tr class="spec-directory-entry daisy-table__row fade fade--show">
    <a href="/livestream" class="daisy-link spec-profile-name">Value1</a>
<tr class="spec-directory-entry daisy-table__row fade fade--show">
    <a href="/livestream" class="daisy-link spec-profile-name">Value2</a>
<tr class="spec-directory-entry daisy-table__row fade fade--show">
.
.
.

Voici le code source du site Web:

import requests 
from bs4 import BeautifulSoup 

# the target we want to open     
url='https://hackerone.com/directory?offers_bounties=true&asset_type=URL&order_direction=DESC&order_field=started_accepting_at'

#open with GET method 
resp=requests.get(url) 

#http_respone 200 means OK status 
if resp.status_code==200: 
    print("Successfully opened the web page") 
    print("The news are as follow :-\n") 

    # we need a parser,Python built-in HTML parser is enough . 
    soup=BeautifulSoup(resp.text,'html.parser')     

    # l is the list which contains all the text i.e news  
    l=soup.find("tr","spec-directory-entry daisy-table__row fade fade--show") 

    #now we want to print only the text part of the anchor. 
    #find all the elements of a, i.e anchor 
    for i in l: 
        print(i.text) 
else: 
    print("Error") 


3 commentaires

Quel est le message d'erreur exact que vous obtenez?


@Azizbro TypeError: l'objet 'NoneType' n'est pas itérable


ok je vais jeter un oeil


3 Réponses :


0
votes

En regardant ce que la demande récupère réellement, il semble que cette page repose sur un contenu dynamique. Le texte suivant est renvoyé dans votre requête:

It looks like your JavaScript is disabled. To use HackerOne, enable JavaScript in your browser and refresh this page.

Vous obtenez "TypeError: l'objet 'NoneType' n'est pas itérable" car sans Javascript, il n'y a pas d'éléments "tr" que BeautifulSoup peut trouver et itérer plus de. Vous devrez utiliser quelque chose comme le sélénium pour simuler un navigateur exécutant Javascript afin d'obtenir le HTML que vous attendez.


0 commentaires

2
votes

On dirait que JS est rendu sur la page. Vous pouvez utiliser à la fois du sélénium et de la belle soupe pour obtenir la valeur.

from selenium import webdriver
import time
from bs4 import BeautifulSoup

driver=webdriver.Chrome()
driver.get("https://hackerone.com/directory?offers_bounties=true&asset_type=URL&order_direction=DESC&order_field=started_accepting_at")
time.sleep(5)
html=driver.page_source
soup=BeautifulSoup(html,'html.parser')
for a in soup.select("a.spec-profile-name[href='\/livestream']"):
    print(a.text)


2 commentaires

Merci pour votre réponse, y a-t-il une raison pour time.sleep (5) ici?


@Zhubarb: Puisque l'élément est chargé dynamiquement par JS. Il est toujours bon de dormir un peu pour charger le contenu d'abord par JS et ensuite obtenir la page_source .



4
votes

JavaScript nécessaire pour afficher le contenu de la page Web. L'utilisation du service prerenderio est un moyen simple / léger d'obtenir les données que vous recherchez sur la page.

Successfully opened the web page
The news are as follow :-

04 / 2019
73
$100
$150-$250

Les données renvoyées par le code ci-dessus:

import requests 
from bs4 import BeautifulSoup 

# the target we want to open
# changed to use prerenderio service 
url='http://service.prerender.io/https://hackerone.com/directory?offers_bounties=true&asset_type=URL&order_direction=DESC&order_field=started_accepting_at'

#open with GET method 
resp=requests.get(url) 

#http_respone 200 means OK status 
if resp.status_code==200: 
    print("Successfully opened the web page") 
    print("The news are as follow :-\n") 

    # we need a parser,Python built-in HTML parser is enough . 
    soup=BeautifulSoup(resp.text,'html.parser')     

    # l is the list which contains all "tr" tags  
    l=soup.findAll("tr","spec-directory-entry daisy-table__row fade fade--show")

    # looping through the list of table rows
    for i in l:
        # checking if the current row is for 'Livestream'
        if i.find('a').text == 'Livestream':
          # printing the row's values except the first "td" tag
          for e in i.findAll('td')[1:]:
            print(e.text)
else: 
    print("Error")


2 commentaires

Merci beaucoup! J'ai modifié le code pour afficher toute la valeur, mais comment pourrais-je obtenir uniquement la valeur "Livestream"?


@Ahmad Je suis heureux de vous aider! J'ai modifié ma réponse pour inclure un exemple montrant uniquement les valeurs de la ligne du tableau "Livestream". J'espère que c'est le résultat que vous recherchez.