需求
为了推广鲜花网络电商,利用微博上的大V做宣传。找到微博上适合做鲜花推广的大V,并给出具体的联络方案。
项目实现细节
第一步: 通过LangChain的搜索工具,以模糊搜索的方式,帮助运营人员找到微博中有可能对相关鲜花推广感兴趣的大V(比如喜欢玫瑰花的大V),并返回UID。
第二步: 根据微博UID,通过爬虫工具拿到相关大V的微博公开信息,并以JSON格式返回大V的数据。
第三步: 通过LangChain调用LLM,通过LLM的总结整理以及生成功能,根据大V的个人信息,写一篇热情洋溢的介绍型文章,谋求与该大V的合作。
第四步: 把LangChain输出解析功能加入进来,让LLM生成可以嵌入提示模板的格式化数据结构。
第五步: 添加HTML、CSS,并用Flask创建一个App,在网络上部署及发布这个鲜花电商人脉工具,供市场营销部门的人员使用。
前两步的实现
第一步 找到大V
- 设计主程序
if __name__ == '__main__':
response_UID = lookup_V(flower_type='玫瑰')
UID = re.findall(r'\d+', response_UID)[0]
- 实现lookup_V
def lookup_V(flower_type: str):
llm = ChatOpenAI(temperature=0, model='gpt-3.5-turbo')
template = """
Given the {flower} I want you to get a related WeiBo UID.Your answer should only contain UID.The URL always starts with https://weibo.com/u for example, if https://weibo.com/u/1669879400 is her 微博, then 1669879400 is her UID.This is only the example don't give me this, but the actual UID.
"""
prompt_template = PromptTemplate(input_variables=["flower"], template=template)
tools = [
Tool(
name="Craw Google for WeiBo page",
func=get_UID,
description="useful when you need get the WeiBo UID"
)
]
agent = initialize_agent(
tools,
llm,
agent=AgentType.ZERO_SHOT_REACT_DESCRIPTION,
verbose=True
)
ID = agent.run(prompt_template.format_prompt(flower=flower_type))
return ID
- 实现工具get_UID
def get_UID(flower: str):
search = SerpAPIWrapper()
res = search.run(flower)
return res
按理说到现在为止其实代码就完成了第一部分的功能了,但是实际运行下来发现并未正确提取出我们需要的UID,经过排查发现是serpAPIWrapper它返回的搜索是文本内容,并没有直接返回对应的link,因此我们需要针对源码做一些调整,方式是通过继承去修改。
class CustomSerpAPIWrapper(SerpAPIWrapper):
def __init__(self):
super(CustomSerpAPIWrapper, self).__init__()
....
....
if "organic_results" in res.keys():
first_organic_result = res["organic_results"][0]
if "snippet" in first_organic_result.keys():
# snippets.append(first_organic_result["snippet"]
snippets.append(first_organic_result["link"])
....
....
def get_UID(flower: str):
"""Searches for Linkedin or twitter Profile Page."""
# search = SerpAPIWrapper()
search = CustomSerpAPIWrapper()
res = search.run(f"{flower}")
return res
第二步 爬取大V资料
- 扩充主程序
person_info = get_data(UID)
- 实现get_data
def get_data(id):
url = "https://weibo.com/ajax/profile/detail?uid={}".format(id)
html = scrape_weibo(url)
response = json.loads(html)
return response
- 实现scrape_weibo(url: str):
# 定义爬取微博用户信息的函数
def scrape_weibo(url: str):
'''爬取相关鲜花服务商的资料'''
headers = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/89.0.4389.82 Safari/537.36",
"Referer": "https://weibo.com"
}
cookies = {
"cookie": '''SINAGLOBAL=3762226753815.13.1696496172299; ALF=1699182321; SCF=AiOo8xtPwGonZcAbYyHXZbz9ixm97mWi0vHt_VvuOKB-u4-rcvlGtWCrE6MfMucpxiOy5bYpkIFNWTj7nYGcyp4.; _sc_token=v'''
}
response = requests.get(url, headers=headers, cookies=cookies)
time.sleep(3) # 加上3s 的延时防止被反爬
return response.text
- 精简输出
将得到的结果信息结果进行一个精简(为了节省token)
import re
def contains_chinese(s):
return bool(re.search('[\u4e00-\u9fa5]', s))
def remove_non_chinese_fields(d):
if isinstance(d, dict):
to_remove = [key for key, value in d.items() if isinstance(value, (str, int, float, bool)) and (not contains_chinese(str(value)))]
for key in to_remove:
del d[key]
for key, value in d.items():
if isinstance(value, (dict, list)):
remove_non_chinese_fields(value)
elif isinstance(d, list):
to_remove_indices = []
for i, item in enumerate(d):
if isinstance(item, (str, int, float, bool)) and (not contains_chinese(str(item))):
to_remove_indices.append(i)
else:
remove_non_chinese_fields(item)
for index in reversed(to_remove_indices):
d.pop(index)