【问题标题】:Using Selenium "find_elements_by_class_name" to retrieve data from website使用 Selenium“find_elements_by_class_name”从网站检索数据
【发布时间】:2020-11-16 11:52:20
【问题描述】:

我正在尝试编写一些 python 代码,并且在 Selenium 上玩得很开心。您可以提供的任何帮助将不胜感激。长话短说,我正在尝试从 Letterboxd.com 获取给定电影的平均评分。例如:

https://letterboxd.com/film/the-dark-knight/

我正在寻找的值是平均评分,保留小数点后 2 位,如果您将鼠标悬停在页面上显示的评分上,您可以看到:

Average Rating 4.43 displayed on mousover

在这种情况下,平均评分是 4.43,这就是我要检索的数字。

到目前为止,我已经成功使用driver.find_elements_by_class_name('average-rating') 获得了小数点后一位的版本 在这种情况下,返回“4.4”。但我需要“4.43”。

我可以在开发者工具中看到正确的值。它出现两次。来到这里:

<span class="average-rating" itemprop="aggregateRating" itemscope itemtype="http://schema.org/AggregateRating">
<a href="/film/the-dark-knight/ratings/" class="tooltip display-rating -highlight" data-original-title="Weighted average of 4.43 based on 444,083&nbsp;ratings">4.4</a>

再一次出现在元数据中:

<meta name="twitter:data2" content="4.43 out of 5">

关于如何正确获取该值的任何建议?非常感谢!

干杯, 阿里

【问题讨论】:

    标签: python selenium selenium-webdriver web-scraping pycharm


    【解决方案1】:

    您可能还想用另一种方法来获得rating 以及users 投票支持该评级的计数。鉴于它们都可以在某些脚本标记内的页面源中使用。

    import re
    import json
    import requests
    
    URL = 'https://letterboxd.com/film/the-dark-knight/'
    
    with requests.Session() as s:
        s.headers['User-Agent'] = 'Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/84.0.4147.89 Safari/537.36'
        r = s.get(URL)
        data = json.loads(re.findall(r"CDATA[^{]+(.*)",r.text)[0])
        rating = data['aggregateRating']['ratingValue']
        user_voted = data['aggregateRating']['ratingCount']
        print(rating,user_voted)
    

    【讨论】:

      【解决方案2】:

      如果您有任何不明白的地方,请找到代码并告诉我。要将鼠标悬停在 Main Rating 上,您应该使用 actionchains。

      from selenium import webdriver
      from selenium.webdriver import ActionChains
      from selenium.webdriver.support.ui import WebDriverWait
      import time
      
      driver = webdriver.Chrome()
      driver.get("https://letterboxd.com/film/the-dark-knight/")
      
      wait = WebDriverWait(driver, 20)
      
      time.sleep(10)
      Main_Rating = driver.find_element_by_class_name('average-rating')
      print("Main Rating is :- " + Main_Rating.text)
      
      time.sleep(5)
      ActionChains(driver).move_to_element(Main_Rating).perform()
      
      More_Rating_info = driver.find_element_by_xpath('//div[@class="twipsy-inner"]').text
      More_Message = More_Rating_info.split()
      
      print("More Rating :- " + More_Message[3])
      

      注意 - 如果这解决了您的问题,请将其标记为答案。

      【讨论】:

      • 谢谢!效果很好!问题一:为什么“time.sleep”一共15秒?因为我要在一个循环中运行几次,所以......很多。我尝试将其减少到每个 0.25 秒,并且似乎工作正常。但我只是好奇:“睡眠”功能有什么原因吗?
      • 你可以隐式等待并删除所有time.sleep()driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
      【解决方案3】:

      使用beautiful souprequests 尝试以下代码:

      使用美汤的好处和要求:

      1. 快速获得结果。

      2. 错误更少。

      3. 对 html 标签的更多访问。

         import requests
         from urllib3.exceptions import InsecureRequestWarning
         requests.packages.urllib3.disable_warnings(InsecureRequestWarning)
         from bs4 import BeautifulSoup as bs
        
         def extract_avg_rating():
        
         movie_name = 'the-dark-knight'
         url = 'https://letterboxd.com/film/' + movie_name
         session = requests.Session()
         url_response = session.get(url,verify=False)
         soup = bs(url_response.text, 'html.parser')
         extracted_meta = soup.find_all('meta')[19]
         extracted_rating = extracted_meta.attrs['content'].split(' ')[0]
         print('Movie ' + movie_name + ' rating ' + extracted_rating)
        
         extract_avg_rating()
        

      在上面的代码movie_name参数中,你可以为ex输入任何电影名称:lucky-grandma,它会给你准确的评级。代码是动态的,可以帮助您提取其他电影评分和其他信息,尽管您只需要做一件事。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-08-23
        • 1970-01-01
        • 2014-12-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多