【问题标题】:Can't traverse into element to scrape rotten tomatoes ratings data using Beautiful Soup and Selenium无法使用 Beautiful Soup 和 Selenium 遍历元素以刮取烂番茄评级数据
【发布时间】:2020-12-30 10:54:02
【问题描述】:

我正在尝试访问包含评分数据的元素,但我不知道如何遍历它(图片链接如下)。评论评分和收视率的 span 元素属于同一类 (mop-ratings-wrap__percentage)。我试图通过分别遍历它们各自的 div('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

And here is the data I want to extract

【问题讨论】:

    标签: python selenium web-scraping beautifulsoup rotten-tomatoes


    【解决方案1】:

    我怀疑

    soup.find()
    

    返回一个字符串而不是你期望的 bs4 对象。所以你在打电话

    "somestring".find()
    

    不接受关键字参数。

    (我会对此发表评论,但我缺乏声誉,抱歉)

    【讨论】:

    • @Thomas 我想对您的答案进行投票,以便您可以使用您的评论特权,但是我不能因为它的小误导(投票给您的另一个问题,现在您可以在任何地方发表评论)。你是对的 find 返回一个字符串,但它是一个 HTML 格式,如果它为 webelement 形成一个字符串,我们可以在返回的元素之上使用 find 方法。我们在这里发布的原因是因为他试图遍历返回的元素,这将使其遍历不再构成 web 元素的返回字符串的每个字母。请参阅我试图解释问题并给出解决方案的答案。
    【解决方案2】:

    问题在于您的循环for a in soup.find('div', attrs={'class':'mop-ratings-wrap__half'}): 您返回了一个元素,然后尝试遍历它,这相当于遍历返回的字符串元素的每个字母。现在你不能在字母上运行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] 打印用户评分。

    【讨论】:

    • 非常感谢,这行得通。问题是,我只希望返回“81%”,因为那是评论家评级。 “75%”是收视率。问题是它们都包含在分类相同的元素中。为此,您知道访问该元素的更好方法吗?谢谢
    • 您已经创建了一个列表,您可以遍历它以获得两个评分(参见解决方案)。 Alternative 使用仅匹配评论家评级的定位器。
    • 太好了,谢谢。如何修改第二个循环,以便将干净的值保存到评级而不是打印到循环中?\
    猜你喜欢
    • 2022-06-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-03-11
    • 1970-01-01
    • 1970-01-01
    • 2012-06-07
    相关资源
    最近更新 更多