Не могу зайти в element, чтобы очистить данные о рейтингах rotten tomatoes, используя Beautiful Soup и Selenium

#python #selenium #web-scraping #beautifulsoup #rotten-tomatoes

#питон #селен #соскабливание полотна #beautifulsoup #rotten-tomatoes #python #очистка веб-страниц

Вопрос:

Я пытаюсь добраться до элемента, который содержит данные рейтинга, но я не могу понять, как перейти к нему (изображение, связанное ниже). Элемент span как для рейтинга критиков, так и для рейтинга аудитории находится в одном классе (mop-ratings-wrap__percentage). Я попытался получить элементы, отдельно перейдя к их соответствующим разделам (‘mop-ratings-wrap__half’ и ‘mop-ratings-wrap__half audience-score’), но я получаю эту ошибку:

 runfile('/Users/*/.spyder-py3/temp.py', wdir='/Users/*/.spyder-py3')
Traceback (most recent call last):

  File "/Users/*/.spyder-py3/temp.py", line 22, in <module>
    cr=a.find('span', attrs={'class':'mop-ratings-wrap__percentage'})

TypeError: find() takes no keyword arguments  

Вот мой код:

 # -*- coding: utf-8 -*-
from selenium import webdriver
from bs4 import BeautifulSoup
import pandas as pd

driver = webdriver.Chrome("/Users/*/Downloads/chromedriver")


critics_rating=[]
audience_rating=[]
driver.get("https://www.rottentomatoes.com/m/bill_and_ted_face_the_music")

content = driver.page_source
soup = BeautifulSoup(content, "lxml")

for a in soup.find('div', attrs={'class':'mop-ratings-wrap__half'}):
      cr=a.find('span', attrs={'class':'mop-ratings-wrap__percentage'})
      critics_rating.append(cr.text)


for b in soup.find('div', attrs={'class':'mop-ratings-wrap__half audience-score'}):
      ar=b.find('span', attrs={'class':'mop-ratings-wrap__percentage'})
      audience_rating.append(ar.text) 

print(critics_rating)
        
    
   

Я следую этой статье:https://www.edureka.co/blog/web-scraping-with-python/#demo

И вот данные, которые я хочу извлечь

Ответ №1:

Я подозреваю, что

 soup.find()
  

возвращает строку, а не объект bs4, как вы ожидаете. Поэтому вы вызываете

 "somestring".find()
  

который не принимает аргументов ключевого слова.

(Я бы прокомментировал это, но мне не хватает репутации, извините)

Комментарии:

1. @Thomas Я хотел проголосовать за ваш ответ, чтобы вы могли использовать свои права на комментарии, однако я не могу, поскольку это немного вводит в заблуждение (проголосовал за другой ваш вопрос, теперь вы можете комментировать где угодно). Вы правы, find возвращает строку, но это формат HTML, и если он формирует строку для webelement, мы можем использовать метод find поверх возвращаемого элемента. Причина, по которой мы здесь выпускаем, заключается в том, что он пытается выполнить цикл по возвращаемому элементу, который заставит его проходить через каждую букву возвращаемой строки, которая больше не является webelement. Смотрите Ответ, который я попытался объяснить проблему и дать решение.

Ответ №2:

Проблема в вашем цикле for a in soup.find('div', attrs={'class':'mop-ratings-wrap__half'}): вы вернули один элемент, а затем пытаетесь пройти через него, что эквивалентно прохождению через каждую букву возвращаемого элемента string. Теперь вы не можете запускать find метод для писем. Решение Если вы хотите перебирать элементы, чтобы использовать find метод поверх них, используйте find_all вместо этого. Поскольку он вернет список webelements , который вы можете просматривать один за другим с помощью цикла.

     content = driver.page_source
soup = BeautifulSoup(content, 'html.parser')
ratings =[]
for a in soup.find_all('div', attrs={'class':'mop-ratings-wrap__half'}):
      cr=a.find('span', attrs={'class':'mop-ratings-wrap__percentage'})
      ratings.append(cr.text)

for rating in ratings:
    print(rating.replace("n", "").strip())
  

Вывод: Приведенный выше код будет напечатан :

введите описание изображения здесь

Примечание: Для печати желаемого результата приведенный выше способ не самый распространенный. Но я попытался ответить на ваши сомнения, а не предложить лучшее решение. Вы можете использовать ratings[0] для печати рейтинга критиков и ratings[1] для печати рейтинга пользователей.

Комментарии:

1. Большое спасибо, это работает. Дело в том, что я хочу вернуть только ‘81%’, так как это рейтинг критиков. ‘75%’ — это рейтинг аудитории. Проблема в том, что они оба содержатся в элементах, которые классифицируются одинаково. С этой целью, знаете ли вы лучший способ доступа к этому элементу? Спасибо

2. вы уже создали список, вы можете просто просмотреть его, чтобы получить оба рейтинга (см. Решение). Альтернативой является локатор, который соответствует только рейтингу критиков.

3. Отлично, спасибо. Как мне изменить второй цикл, чтобы чистые значения сохранялись в рейтингах, а не просто печатались в цикле?