Streamlit可视化之设计案例分析小助手
目录
一、背景
二、代码
一、背景
本文设计了一个设计案例分析小助手,旨在通过对设计网的信息爬取与可视化呈现,结合大模型的语言能力,对设计案例进行简单分析。
可视化通过Streamlit框架实现,爬虫通过requests+BeautifulSoup实现,大模型是调用openai接口,数据来源于设计网站。
二、代码
爬取标题、内容、地址、图片,代码如下:
def get_item_information(url):
'''
爬取标题、内容、地址、图片
'''
web = rq.get(url)
web.encoding = 'utf-8'
soup = BeautifulSoup(web.text,'html.parser')
#获取标题
title = soup.title.get_text(strip=True)[:-5]
#获取内容
paragraphs = soup.find_all('p', class_='p1')
content = ''.join(paragraph.get_text(strip=True) for paragraph in paragraphs)
content = content.replace('设计图纸 ▽', '')
#获取地址
p3_list = soup.find_all('p', class_='p3')
address_list = [address.get_text(strip=True) for address in p3_list]
address_list = [address for address in address_list if '项目地' in address]
return_address = address_list[-1].replace('项目地址','').replace('项目地点','').replace(':','')
#获取图片
jpg_element = soup.find_all('img')
jpg_pattern = re.compile(r'src="([^"]*\.jpg)"')
jpg_url_list = jpg_pattern.findall(str(jpg_element))
for jpg_url in jpg_url_list:
picture = rq.get(jpg_url)
if picture.status_code==200:
jpg_path = os.path.basename(jpg_url)
with open('./jpg/'+jpg_path,"wb") as f:
f.write(picture.content)
break
return title,content,return_address,'./jpg/'+jpg_path
进入页面,展示气球特效:
if not button_clicked:
st.balloons()
st.session_state.button_clicked = True
效果如下:
展示爬取的标题与图片:
# 创建下拉选择框
option = st.selectbox(
'选择一个你感兴趣的设计项目',
df['title'])
if option:
st.session_state.messages = []
content = get_content_by_title(option)
local_image_path = get_image_by_title(option)
address = get_address_by_title(option)
lng_and_lat = address_geo_api(address)
st.image(local_image_path, caption=option, use_column_width=True)
st.markdown("#### 该项目的地理位置信息是:")
st.markdown(address)
st.map(lng_and_lat)
地理位置是根据项目地址调用百度地图API(http://api.map.baidu.com/geocoding/v3/)获取的经纬度信息:
def address_geo_api(query):
"""
地理位置正向经纬度编码
"""
lng, lat = '116.403901', '39.914466'
try:
# 1、设置url和3个参数(输出格式,key,要翻译的地址)
url = 'http://api.map.baidu.com/geocoding/v3/'
output = 'json'
ak = ''
address = quote(query)
# 2、拼接get请求(url?参数1=值1&参数2=值2&参数3=值3)
request = url + '?' + 'address=' + address + \
'&output=' + output + '&ak=' + ak
# 3、urlopen发送请求,获得response
response_file = urlopen(request)
# 4、读取response字符串
response_str = response_file.read().decode()
# 5、str转json
response_json = json.loads(response_str)
# 6、读json
lat = response_json['result']['location']['lat']
lng = response_json['result']['location']['lng']
if response_json['result']['level'] == 'NoClass':
lng, lat = '116.403901', '39.914466'
except Exception as e:
print(e)
finally:
return pd.DataFrame([[lat,lng,query]],columns=['lat', 'lon','location'])
大模型能力是使用OpenAI API,包括文生文和文生图:
# 使用ChatGPT获取案例摘要的函数
def chat_gpt(text,target):
client = OpenAI(base_url=os.environ["OPENAI_API_BASE"],api_key=os.environ["OPENAI_API_KEY"])
response = client.chat.completions.create(
model="gpt-3.5-turbo",
messages=[
{"role": "user", "content": text},
{"role": "assistant", "content": target}
],
temperature=0.3,
max_tokens=1000
)
# 输出生成的总结
summary = response.choices[0].message.content
return summary
st.markdown("---")
st.markdown("#### 文本生成")
col1, col2,col3,col4 = st.columns(4)
with col1:
check = st.button("生成摘要")
# 点击生成摘要按钮后的操作
if check:
with st.spinner("生成摘要中..."):
st.session_state.messages = []
content = get_content_by_title(option)
summary = chat_gpt(content,"在50字以内,总结这篇文章的主要内容")
st.session_state.messages.append({"role": "assistant", "content": "这篇文章的摘要如下:\n\n"+summary})
with col2:
keywords = st.button("生成关键词")
if keywords:
with st.spinner("生成关键词中..."):
st.session_state.messages = []
content = get_content_by_title(option)
words = chat_gpt(content,"总结这篇文章最重要的10个设计要素关键词")
st.session_state.messages.append({"role": "assistant", "content": "生成的关键词如下:\n\n"+words})
with col3:
sjsl = st.button("借鉴设计思路")
if sjsl:
st.session_state.messages = []
content = get_content_by_title(option)
design = chat_gpt(content,"请提供一些可以从这个案例中借鉴的设计思路")
st.session_state.messages.append({"role": "assistant", "content": "可借鉴的设计思路如下:\n\n"+design})
with col4:
check_flash = st.button("刷新")
if check_flash:
st.session_state.messages = [] # 点击刷新后清空现有的页面内容