问题描述
我正在尝试将笔记本导出为 HTML,笔记本内部有多个交互式面板。
import panel as pn
import hvplot as hv
import holoviews as hv2
from bokeh.io import output_notebook,push_notebook,show,save,output_file
from bokeh.resources import INLINE
def plot_ts(feature=Spends[0],target=Target[0]):
fig = df[target].plot.line(title=target)
fig += df[feature].plot.area(title=feature)
return fig.cols(1)
kw = dict(feature=sorted(list(Spends + Misc)))
panel1 = pn.interact(plot_ts,**kw)
panel1
现在我正在运行以下行:
!jupyter nbconvert --to html index.ipynb --no-input --no-prompt
问题是我的面板变得陈旧(相应的数据未嵌入其中)。
如果我使用以下行一一保存面板,我将获得带有嵌入数据的面板。
panel1.save('test.html',embed=True,resources=INLINE)
我尝试以这种方式保存所有面板,然后使用 Selenium 合并不同的 HTML 文件,但它不起作用。
我尝试将面板附加到彼此
all_panels.append(panel1).append(panel2).append(panel3)
all_panels.save("all_panels.html",embed=True)
生成的 HTML 文件有问题,有些面板可以工作,有些则不能。
如果有人对如何使这项工作有任何想法,那就太棒了。
谢谢
解决方法
使用 BeautifulSoup,我设法创建了一个 HTML 文件,其中包含保存为独立 html 文件及其嵌入数据的不同面板。
我认为它可能对其他人有用,所以这里是代码:
# Imports
from bs4 import BeautifulSoup,Tag
import glob
# List the filepaths corresponding to panels exported to html using 'panel_object.save("panel_name.html",embed=True)'
panels = glob.glob("/Users/username/Documents/data_exploration/panels/*.html")
panels_soup = []
# Read files and append their soup to a list
for panel in panels:
with open(panel) as fp:
panel = BeautifulSoup(fp,'html.parser')
panels_soup.append(panel)
# HTML base
soup = BeautifulSoup()
html = soup.new_tag("html")
soup.append(html)
# Append the head tag of one of the panels (it includes the bokeh/holoviews scripts)
soup.html.append(panels_soup[0].find("head"))
# Append an empty body tag
body = soup.new_tag("body")
soup.html.append(body)
# Loop on soups
for panel in panels_soup:
divs = panel.find_all("div",attrs={"class":"bk-root"})
data = panel.find_all('script')[-2]
script = panel.find_all('script')[-1]
panels_dict.append({"div_1":divs[0],"div_2":divs[-1],"data":data,"script":script})
# Append panels divs to the body of the page
for panel in panels_dict:
soup.body.insert(1,panel["div_2"])
soup.body.insert(1,panel["div_1"])
# Append the data at the end of the page
for panel in panels_dict:
soup.body.insert(len(soup.body.contents),panel["data"])
# Append the scripts at the end of the page
for panel in panels_dict:
soup.body.insert(len(soup.body.contents),panel["script"])
# Export HTML file containing all the panels
with open("index.html","w") as fp:
fp.write(soup.prettify(formatter="html"))