python:无法使用 BeautifulSoup 从 html 获取特定数据

python: can't get specific data from html using BeautifulSoup

我正在尝试使用 beautifulsoup 和 urllib 从特定网页中提取给定的百分比:https://app.safespace.io/api/display/live-occupancy/86fb9e11?view=percent。我对这样的东西很陌生。 这是我的意大利面条代码:

import urllib.request

contentSource = urllib.request.urlopen('https://app.safespace.io/api/display/live-occupancy/86fb9e11?view=percent')
read_content = contentSource.read()

from bs4 import BeautifulSoup
soup = BeautifulSoup(read_content, 'html.parser')

try1 = soup.find("span", {"id": "occupancyPct"})

print(try1)

在原始网页上,当“inspect element”百分比时,百分比实际显示在 html、as highlighted.

但是,我的代码的打印输出是 <span class="text-xl" id="occupancyPct" style="margin-bottom: auto;"></span>

请注意我的代码输出如何不显示输出中的百分比,这与实际页面的 html 不同。我做错了什么?

我也会接受“你很笨因为 X,你应该做 Y”,或者它的一些变体。

问题是百分比不是静态字段,它是 generated/calculated 和 JavaScript。据我所知,对于这种类型的网络抓取,您只能在 JavaScript 或执行某些操作之前提取源代码。因此该字段保持空白.. 而不是 chrome 检查工具尝试查看原始源代码,不幸的是该字段是空的。

这里是 JavaScript 填充百分比字段的代码:

var setters = {
          bgClass: (function() {
            var bgSetter = getNumericClassSetter(elms.bg);

            return function(occupants) {
              // get percent, floored to the nearest 5 percent
              var pct = Number(`${ Number(`${occupants}e+2`) / Number(`${maxCapacity}e+2`) }e+2`);
              var floor = pct - (pct % 5);

              if (floor >= 100) {
                bgSetter(105);
              }
              else {
                bgSetter(floor);
              }
            };
          })(),
          occupancyPct: (function(occupants) {
            elms.occupancyPct.innerText = Math.min(100, Math.floor((occupants / maxCapacity) * 100)) + '%';
          }),
        };

据我所知,百分比是使用给定变量计算的。可以用自己的代码计算百分比吗?

它没有显示百分比,因为该百分比是稍后通过 javascript 计算的。而你得到的HTML是第一个没有百分比的

答案很简单: 你必须使用 selenium

为什么?

你需要一个导航器,所以javascript代码会被执行,你要找的百分比就会在那里,在页面的代码源中,你所要做的就是找到一个获得它的技巧。

页面是动态加载的,因此requests不支持。我们可以 Selenium 作为抓取页面的替代方法。

安装:pip install selenium.

here 下载正确的 ChromeDriver。

from time import sleep
from selenium import webdriver
from bs4 import BeautifulSoup

URL = "https://app.safespace.io/api/display/live-occupancy/86fb9e11?view=percent"
driver = webdriver.Chrome(r"c:\path\to\chromedriver.exe")
driver.get(URL)
# Wait for page to fully render
sleep(5)

soup = BeautifulSoup(driver.page_source, "html.parser")
print(soup.find("span", {"id": "occupancyPct"}).text)

driver.quit()