【问题标题】:Beautiful Soup 4 findall() not matching elements from the <img> tagBeautiful Soup 4 findall() 与 <img> 标签中的元素不匹配
【发布时间】:2019-12-29 14:04:45
【问题描述】:

我正在尝试使用 Beautiful Soup 4 帮助我从 Imgur 下载图像,尽管我怀疑 Imgur 部分是否相关。例如,我在这里使用网页:https://imgur.com/t/lenovo/mLwnorj

我的代码如下:

import webbrowser, time, sys, requests, os, bs4      # Not all libraries are used in this code snippet
from selenium import webdriver

browser = webdriver.Firefox()
browser.get("https://imgur.com/t/lenovo/mLwnorj")

res = requests.get(https://imgur.com/t/lenovo/mLwnorj)
res.raise_for_status()
soup = bs4.BeautifulSoup(res.text, features="html.parser")

imageElement = soup.findAll('img', {'class': 'post-image-placeholder'})
print(imageElement)

Imgur 链接上的 HTML 代码包含如下部分:

<img alt="" src="//i.imgur.com/JfLsH5y.jpg" class="post-image-placeholder" style="max-width: 100%; min-height: 546px;" original-title="">

我是通过使用 Inspect Element 中的指向和单击工具选择页面上的第一个图像元素找到的。

问题是我希望 imageElement 中有两个项目,每个图像一个,但是,打印函数显示[]。我也尝试过其他形式的soup.findAll('img', {'class': 'post-image-placeholder'}),例如soup.findall("img[class='post-image-placeholder']"),但这并没有什么不同。

另外,当我使用

imageElement = soup.select("h1[class='post-title']")

,只是为了测试,打印函数确实返回了一个匹配,这让我怀疑它是否与标签有关。

[<h1 class="post-title">Cable management increases performance. </h1>]

感谢您的时间和精力

【问题讨论】:

  • 您是否在第一次请求页面时运行print(res.text) 来实际验证图像是否在 HTML 中?网站加载页面然后使用 JavaScript 插入元素是很常见的。
  • @SpencerD 啊,我刚刚运行它,但找不到任何图像标签。感谢您指出了这一点!您知道如何获取更新的 HTML 吗?谢谢!
  • 是的,等一下,我会按照这些思路发布答案。

标签: python python-3.x beautifulsoup


【解决方案1】:

如果网站将在页面加载后插入对象,您将需要使用 Selenium 而不是 requests

from bs4 import BeautifulSoup
from selenium import webdriver

url = 'https://imgur.com/t/lenovo/mLwnorj'
browser = webdriver.Firefox()
browser.get(url)
soup = BeautifulSoup(browser.page_source, 'html.parser')
images = soup.find_all('img', {'class': 'post-image-placeholder'})

[print(image['src']) for image in images]

# //i.imgur.com/JfLsH5yr.jpg
# //i.imgur.com/lLcKMBzr.jpg

【讨论】:

    【解决方案2】:

    这里的根本问题似乎是第一次加载页面时实际的&lt;img ...&gt; 元素不存在。在我看来,最好的解决方案是利用你已有的 selenium webdriver 来获取图像。 Selenium 将允许页面正确呈现(使用 JavaScript 和所有),然后找到您关心的任何元素。

    例如:

    import webbrowser, time, sys, requests, os, bs4      # Not all libraries are used in this code snippet
    from selenium import webdriver
    
    # For pretty debugging output
    import pprint
    
    
    browser = webdriver.Firefox()
    browser.get("https://imgur.com/t/lenovo/mLwnorj")
    
    # Give the page up to 10 seconds of a grace period to finish rendering
    # before complaining about images not being found.
    browser.implicitly_wait(10)
    
    # Find elements via Selenium's search
    selenium_image_elements = browser.find_elements_by_css_selector('img.post-image-placeholder')
    pprint.pprint(selenium_image_elements)
    
    # Use page source to attempt to find them with BeautifulSoup 4
    soup = bs4.BeautifulSoup(browser.page_source, features="html.parser")
    
    soup_image_elements = soup.findAll('img', {'class': 'post-image-placeholder'})
    pprint.pprint(soup_image_elements)
    

    我不能说我已经测试了这段代码,但一般概念应该有效。


    更新:

    我继续测试了这一点,修复了代码中的一些错误,然后得到了我希望看到的结果:

    【讨论】:

      猜你喜欢
      • 2018-01-17
      • 1970-01-01
      • 1970-01-01
      • 2020-07-04
      • 1970-01-01
      • 2017-12-20
      • 1970-01-01
      • 1970-01-01
      • 2019-02-20
      相关资源
      最近更新 更多