python-3.x - 如何使用 BS 或 selenium 从 gchart 中抓取数据

标签 python-3.x selenium beautifulsoup

我希望从图表中提取数据,当您将鼠标悬停在图表上时可以查看该数据,但该数据不会出现在源代码中。有什么办法可以提取这个吗?我对此很陌生,但到目前为止还没有在任何地方找到对此的讨论。这似乎是 Selenium 的工作,或者可能是我从未听说过的很酷的东西。

下面的代码涉及大麻素部分,这是我感兴趣的领域,以及具有相同问题的萜烯部分。

https://www.dinafem.org/en/amnesia-cbd/

<div id="product-cannabinoids-chart-wrapper"> <div data-chart_id="product_cannabinoids" class="auto-gchart" id="product_cannabinoids_chart"></div> </div> <form data-chart_id="product_cannabinoids" class="auto-gchart-filters" style="display: none;"> <input type="hidden" name="product_sku" value="0003142"/> </form>

最佳答案

这些表来自 POST 请求。您可以使用纯请求来模仿这一点。

方法如下:

import json

import requests
from bs4 import BeautifulSoup

url = "https://www.dinafem.org/en/amnesia-cbd/?PageSpeed=noscript"

headers = {
    "User-Agent": "Mozilla/5.0 (X11; Linux x86_64) "
                  "AppleWebKit/537.36 (KHTML, like Gecko) "
                  "Chrome/90.0.4430.85 Safari/537.36",
    "X-Requested-With": "XMLHttpRequest"
}

with requests.Session() as connection:
    product_sku = BeautifulSoup(
        connection.get(url).text,
        "html.parser",
    ).find("input", {"name": "product_sku"})["value"]

    chart_ids = ["product_cannabinoids", "product_terpenes"]

    payload = {
        "action": "get_gchart_data",
        "filters": f"product_sku={product_sku}",
    }

    charts = []
    for chart_id in chart_ids:
        payload.update({"chart_id": chart_id})
        charts.append(connection.post(url, headers=headers, data=payload).json())

print(json.dumps(charts[0], indent=2))

输出:

{
  "error": 0,
  "chart_id": "product_cannabinoids",
  "data": [
    [
      "Cannabinoid",
      "(%)"
    ],
    [
      "CBD",
      11.64
    ],
    [
      "THC",
      7.37
    ],
    [
      "CBC",
      0.7
    ],
    [
      "CBG",
      0.46
    ],
    [
      "THCV",
      0.04
    ],
    [
      "CBN",
      0.01
    ]
  ],
  "debug": {
    "total": 20.220000000000002
  }
}

您甚至可以绘制该图以获得网站上的真实图表。

将其添加到您的导入中:

import matplotlib.pyplot as plt

然后输入:

data = [i[1] for i in charts[1]["data"]]
info = [i[0] for i in charts[1]["data"]]
fig = plt.figure(figsize=(10, 7))
plt.pie(data, labels=info)
plt.show()

要得到这个:

enter image description here

关于python-3.x - 如何使用 BS 或 selenium 从 gchart 中抓取数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/67254837/

相关文章:

python - 使用 PhantomJs 拒绝连接

python - 在 Python 中使用 Chromedriver 启用 Flash

python - 将抓取的数据写入 csv 文件时出错

python - 尝试使用 BeautifulSoup 访问 XML 中的嵌套元素

python - 不可哈希类型,从集合中删除重复项但保留条目顺序

python - 如何将任何数字四舍五入到最接近的 5 的倍数?

python-3.x - 如何切片pandas.DatetimeIndex?

java - 使用正则表达式时appium驱动程序抛出异常?

python-3.x - 在我的二分搜索算法中,Python 在列表中找不到 0 个索引成员

Python BeautifulSoup - 防止特定的模糊/损坏标签匹配