【问题标题】:How to Scrape Specific Content using Beautifulsoup / Selenium如何使用 Beautifulsoup / Selenium 抓取特定内容
【发布时间】:2019-08-14 14:37:20
【问题描述】:

我正在尝试在 youtube 上抓取每个 cmets 的点赞数。

我的整体代码循环/向下滚动,但为简单起见,我只显示给我带来问题的部分。我是网络抓取的新手。这是我尝试过的:

page_url="https://www.youtube.com/watch?v=TQG7m1BFeRc"
driver = webdriver.Chrome('C:/Users/Me/Chrome Web 
Driver/chromedriver.exe')
driver.get(page_url)
html_source = driver.page_source
html = driver.find_element_by_tag_name('html')
soup=bs(html.text,'html.parser')
soup_source=bs(html_source,'html.parser')

然后我尝试提取喜欢的数量:

for div in soup.find_all('div', class_="style-scope ytd-comment-action- 
buttons-renderer"):
    a=str(div.text)
    print(a)

但这不会返回任何内容。当我检查soup_source 内容时,我可以看到以下我要抓取的信息所在的位置:

<span aria-label="473 likes" class="style-scope ytd-comment-action- 
buttons-renderer" hidden="" id="vote-count-left">
    473

我尝试了一些方法,例如:

html = driver.(By.ID, 'vote-count-left')

但它不起作用。如果有人可以请帮助,将不胜感激。谢谢

【问题讨论】:

    标签: python selenium beautifulsoup


    【解决方案1】:

    这将起作用:

    from selenium import webdriver
    from selenium.webdriver.common.by import By
    from selenium.webdriver.support.ui import WebDriverWait
    from selenium.webdriver.support import expected_conditions as EC
    
    from bs4 import BeautifulSoup
    
    driver_path = r'C:/Users/Me/Chrome Web Driver/chromedriver.exe'
    driver_path = r'D:\Programming\utilities\chromedriver.exe'
    
    page_url = "https://www.youtube.com/watch?v=TQG7m1BFeRc"
    driver = webdriver.Chrome(driver_path)
    driver.get(page_url)
    WebDriverWait(driver, 10).until(EC.presence_of_element_located((By.XPATH, '//*[@id="owner-name"]/a')))
    driver.execute_script('window.scrollTo(0, 768);')
    WebDriverWait(driver, 10).until(EC.presence_of_element_located((By.ID, 'vote-count-left')))
    
    html = driver.page_source
    soup = BeautifulSoup(html, 'html.parser')
    result = [element.text.strip() for element in soup.find_all('span', {'id': 'vote-count-left'})]
    
    result
    

    输出:

    ['1.9K', '153', '36', '340', '474', '1.5K', '296', '750', '0', '18', '2K', '20', '17', '8', '192', '459', '56', '10', '0', '19']
    

    这实际上比乍看之下更复杂,因为 YouTube 确实加载 cmets 部分直到您真正向下滚动。因此,我必须包含等待页面完全加载并向下滚动的逻辑,然后再等待直到实际加载 cmets。

    另外,您应该一直在寻找 span,而不是 div - 这是您的原始查询未找到任何内容的原因。

    【讨论】:

      【解决方案2】:

      按 ID #vote-count-middle 获取所有跨度,并获取包含喜欢的属性 aria-label,并使用正则表达式仅精确数字。

      注意:此代码尚未经过测试,但对于您要实现的目标有明确的路径。

          import re
          reg = re.compile(r'(?<=[0-9]\s[A-Z]\s)[0-9\-\s]+')
      
          likeArray = driver.find_element_by_xpath('//*[@id="vote-count-middle"]')
          for row in likeArray:
          # Extract from span the value 000 Likes on internal html attribute
          value = row.get_attribute("aria-label").text
          if reg.search(value):
             # Remove text (Likes text)
             result = reg.search(value)
             # Print result
             print(result)
      

      【讨论】:

      • 您好,感谢您的帮助,抱歉回复晚了,我昨晚睡得早。我收到以下错误消息:TypeError: 'WebElement' object is not iterable
      【解决方案3】:

      这个怎么样:

      html = """
        <span id="vote-count-left" class="style-scope ytd-comment-action-buttons-renderer" aria-label="474 likes" hidden="">
          474
        </span>
      
        """
      soup = BeautifulSoup(html, "lxml")
      data = soup.find_all("span")
      for i in data:
           print(i.text)
      

      输出:

          474
      

      【讨论】:

      • 您是否真正查看过 YouTube 页面源代码?
      • 您好,感谢您的帮助,抱歉回复晚了,我昨晚睡得早。在页面源中,我可以看到以下内容,但无法提取: 或者,如果你看一下 youtube 喜欢的页面,它们不容易刮掉,其余的都可以,但是喜欢我有问题:-(
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-09-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多