任何人都可以建议一种方法来抓取a
<script>
标签中的数据,具体来说,在本例中是来自AEMO的30分钟表(
https://www.aemo.com.au/aemo/apps/visualizes/ elec-nem-priceanddemand.html
)。
要获取数据表,我需要单击在网站上显示该表的按钮或下载按钮。然而,这里的障碍是,当我尝试使用 Selenium 抓取表格时,按钮和表格文本隐藏在
<script>
标签后面。
这是迄今为止我的代码:
# import libraries
import urllib.request
from bs4 import BeautifulSoup
from selenium import webdriver
import time
import pandas as pd
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
url = "https://www.aemo.com.au/aemo/apps/visualisations/elec-nem-priceanddemand.html"
browser = webdriver.Safari(executable_path='/usr/bin/safaridriver')
browser.get(url)
try:
print(browser.page_source)
except:
print("not found")
finally:
browser.quit()
和部分结果是:
<body aurelia-app="visualisation-main" data-gr-c-s-loaded="true">
<div class="splash">
<div class="message"><span class="icon-spinner"></span></div>
</div>
<script src="jspm_packages/system.js"></script>
<script src="config.js"></script>
<script>
System.import('aurelia-bootstrapper');
</script>
</body></html>
数据在
script
标签中不可见,因为它是由运行在网站上的 JavaScript 代码动态加载的。你的抓取方法需要考虑这一点。以下是如何使用 Selenium 和 BeautifulSoup 从 AEMO 网站抓取数据的步骤:
-
使用 Selenium 加载页面并渲染 JavaScript: 你已经正确地使用 Selenium 加载页面了。Selenium 会等待页面及其 JavaScript 内容加载完毕。
-
定位包含数据的
script
标签: 你需要检查页面的 HTML 源代码(可以使用浏览器的开发者工具),并找到包含所需数据的script
标签。查找标签内的特定模式、ID 或类名,以便你能够使用 BeautifulSoup 准确地定位它。 -
使用 BeautifulSoup 提取
script
标签的内容: 找到正确的script
标签后,使用 BeautifulSoup 提取其内容。 -
从 JavaScript 代码中解析数据: 提取的
script
标签内容将包含 JavaScript 代码,很可能是一个数组或 JSON 对象。你将需要使用字符串操作或正则表达式来清理数据,并将其转换为可用的 Python 数据结构(例如,列表或字典)。 -
将数据结构化为 DataFrame: 最后,使用 pandas 将解析后的数据组织到 DataFrame 中,以便进行进一步的分析或操作。
以下是一个使用修改后的代码示例,展示了这些步骤:
import urllib.request
from bs4 import BeautifulSoup
from selenium import webdriver
import time
import pandas as pd
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
import json
url = "https://www.aemo.com.au/aemo/apps/visualisations/elec-nem-priceanddemand.html"
browser = webdriver.Safari(executable_path='/usr/bin/safaridriver')
browser.get(url)
# 等待特定元素加载,表明数据已准备好
wait = WebDriverWait(browser, 10)
element = wait.until(EC.presence_of_element_located((By.CSS_SELECTOR, '.highcharts-series-group')))
# 获取页面源代码
page_source = browser.page_source
soup = BeautifulSoup(page_source, 'html.parser')
# 查找包含数据的 script 标签(调整选择器以匹配实际的 HTML 结构)
script_tag = soup.find('script', text=lambda text: 'seriesData' in text)
# 从脚本标签中提取数据
script_content = script_tag.text
start = script_content.find('seriesData:') + len('seriesData:')
end = script_content.find('}],', start) + 2
json_data = json.loads(script_content[start:end])
# 提取相关数据点
data_points = json_data[0]['data']
# 使用 pandas 创建 DataFrame
df = pd.DataFrame(data_points)
# 打印 DataFrame
print(df)
browser.quit()
这段代码首先等待一个特定元素加载,该元素表示数据已经存在于页面上。然后,它找到包含数据的
script
标签,提取 JSON 数据,并将其转换为 pandas DataFrame。
请注意,这只是一个示例,你可能需要根据网站的结构和包含所需数据的
script
标签调整选择器和解析逻辑。