Cela peut sembler simple, mais je n'ai pas réussi à le faire fonctionner. Je viens de commencer à apprendre le grattage récemment et j'ai rencontré ce problème. J'ai essayé le code en python REPL et il semble fonctionner, mais je ne sais pas pourquoi quand je l'ai codé, cela ne fonctionnerait pas.

Ceci est mon code ci-dessous btw. Donc, ce que j'essaie de faire, c'est d'extraire le titre de l'article, le lien et l'image de mon programme et voici ce que j'ai ci-dessous.

from urllib.request import urlopen
from bs4 import BeautifulSoup
import requests
import json

beauty_result=[]

def scrape_b2():
    soup = BeautifulSoup(urlopen('https://www.instyle.com/beauty'), 'lxml')
    url = 'https://www.instyle.com'
    for article in soup.find_all('article',class_='component tile media image-top type-article'):
        for img in article.find_all('div',class_='component lazy-image thumbnail'):
            for a in article.find('h3'):
                beauty_result.append(json.dumps({
                    'title':a.get_text(strip=True),
                    'link':url+article.find('a')['href'],
                    'image':img.get('data-src')
                }))
    print(beauty_result)

if __name__ == '__main__':
    scrape_b2()

Et voici toute la trace de l'erreur que j'ai eue:

D:\Coding\Python\webscrape env>python app.py
Traceback (most recent call last):
File "app.py", line 37, in <module> scrape_b2()
File "app.py", line 28, in scrape_b2 'title':a.get_text(strip=True),
File "D:\Coding\Tools\Anaconda3\envs\webscraper_practice\lib\site-packages\bs4\element.py", line 742, in getattr self.__class__.__name__, attr))
AttributeError: 'NavigableString' object has no attribute 'get_text' 

C'est ce que j'ai résolu avec:

def scrape_b2():
    soup = BeautifulSoup(urlopen('https://www.instyle.com/beauty'), 'lxml')
    url = 'https://www.instyle.com'
    for article in soup.find_all('article',class_='component tile media image-top type-article'):
        for img in article.find_all('div',class_='component lazy-image thumbnail'):
            h3 = article.find('h3')
            a_link = h3.find('a')
            beauty_result.append(json.dumps({
                'title': a_link.get_text(strip=True),
                'link': url + a_link.get('href'),
                'image': img.get('data-src')
                }))
    print(beauty_result)
1
Kenneth Choo 11 mars 2019 à 14:07

2 réponses

Meilleure réponse

Votre erreur est due au fait que vous ne pouvez pas utiliser la méthode get_text(), qui est spécifique à l'objet Bs4.

Ce que vous pouvez faire, c'est:

h3 = article.find('h3')
a_link = h3.find('a')
beauty_result.append(json.dumps({
    'title': a_link.get_text(strip=True),
    'link': url + a_link.get('href'),
    'image': img.get('data-src')
     }))

Le code précédent remplace la boucle for a in article.find('h3'):

0
Maaz 11 mars 2019 à 13:17

Le script suivant vous donnera les différents titres d'articles et leurs liens concernant ce site. Il semble que le contenu spécifique de cette page soit généré dynamiquement, mais en réalité, il ne l'est pas. Ils sont présents dans la page source avec des noms de classe différents.

import requests
from bs4 import BeautifulSoup
from urllib.parse import urljoin

URL = "https://www.instyle.com/beauty"

def get_article_info(link):
    res = requests.get(link)
    soup = BeautifulSoup(res.text, 'lxml')
    for article in soup.select('.media-body h3.headline a[href^="/"]'):
        title = article.get_text().strip()
        link = urljoin(link,article.get("href").strip())
        yield {"title":title,"url":link}

if __name__ == '__main__':
    for item in get_article_info(URL):
        print(item['title'],item['url'])
0
SIM 11 mars 2019 à 14:21