如何抓取水平条形图?

How to scrape a horizontal bar chart?

提问人:AlwaysJunior 提问时间:9/21/2022 最后编辑:IMSoPAlwaysJunior 更新时间:9/21/2022 访问量:52

问:

你可以在这个地址找到我想抓取的图表:https://www.algopoly.com/res-rapor.html

我的愿望是:

KARABEL RES 5.23 TL/MWh
GÖKÇEDAĞ RES 21.28 TL/MWh
.
.
.
HAMSİ RES 486.47TL/MWh

我试过:

from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from webdriver_manager.chrome import ChromeDriverManager
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC


url = 'https://www.algopoly.com/res-rapor.html'

options = webdriver.ChromeOptions()
options.add_argument("start-maximized")
options.add_experimental_option('excludeSwitches', ['enable-logging'])
driver = webdriver.Chrome(options=options, service=Service(ChromeDriverManager().install()))
driver.get(url)
WebDriverWait(driver, 20).until(EC.presence_of_all_elements_located((By.XPATH, "//iframe[@id='518061208646906024']")))

iframe_element = driver.find_element(By.XPATH, "//iframe[@id='518061208646906024']")
data = driver.switch_to.frame(iframe_element)
print(data)

我什么也得不到。是否可以用硒刮掉这张图表?

蟒蛇

评论

0赞 Arundeep Chohan 9/21/2022
*[local-name()='svg']//*[local-name()='g']//*[local-name()='text'] 这并不完全正确,但您的元素位于带有 g 和 text 元素的 svg 中,这些元素应该类似于这个 XPath。
0赞 AlwaysJunior 9/21/2022
我也试图报废svg,但它不起作用。我遇到了非常奇怪的错误。现在我开始寻找是否有可能这样做。

答:

0赞 Barry the Platipus 9/21/2022 #1

任务并非易事:该条形图的数据是从其他地址提取的。如果你检查 HTML,你可以看到一个 iframe - 你需要抓取该 iframe 的源代码,以获得实际的图表数据。这里有一种方法,避免使用硒:

import requests
from bs4 import BeautifulSoup as bs
import json

headers = {
'User-Agent': 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/104.0.5112.79 Safari/537.36'
}

r = requests.get('https://s3.eu-west-1.amazonaws.com/algopoly.com/res_rapor/index.html', headers=headers)

soup = bs(r.text, 'lxml')
script = soup.select_one('script[type="application/json"]')
json_obj = json.loads(script.text)
soup = bs(json_obj['x']['html'], 'lxml')
# print(soup.prettify())
elements = soup.select('rect[fill-opacity="1"]')
for el in elements:
    print(el.get('title'))

终端结果:

None
None
Org: EGENER<br>UEVCB: KARABEL RES<br>Toplam Dengesizlik: 4095 TL<br>Toplam KÃPST: 616 TL<br>Toplam Ãretim: 901.08 MWh
Org: ROTOR<br>UEVCB: GÃKÃEDAÄ RES<br>Toplam Dengesizlik: 883763 TL<br>Toplam KÃPST: 170890 TL<br>Toplam Ãretim: 49571.7 MWh
Org: YENİ BELEN<br>UEVCB: ÅENBÃK RES(YENİ BELEN ENR.)<br>Toplam Dengesizlik: 360862 TL<br>Toplam KÃPST: 97310 TL<br>Toplam Ãretim: 17903.76 MWh
Org: BELEN<br>UEVCB: BELEN ELEKTRİK ÃRETİM A.Å.<br>Toplam Dengesizlik: 467731 TL<br>Toplam KÃPST: 87781 TL<br>Toplam Ãretim: 20176 MWh
Org: İMBAT<br>UEVCB: SARITEPE RES<br>Toplam Dengesizlik: 590565 TL<br>Toplam KÃPST: 121483 TL<br>Toplam Ãretim: 24895 MWh
[...]

期望做一些数据清理。您还可以检查响应,并查看从 json 中提取的 xml 数据中是否有其他需要的数据。

评论

0赞 AlwaysJunior 9/21/2022
非常感谢,您对编码lxml有什么建议吗?因为我认为我应该在创建script(<class 'bs4.element.Tag'>)之前尝试编码。