跳过正文

2026-04-29

·

最近刘总分配了一个新任务,就是从抖店后台抓取抖店的订单数据,保存到本地的excel,还是有所经验可以总结的

先介绍方案,先通过影刀来抓取网页数据,并保存到本地,在将其本地数据通过调用大模型进行清理,再通过python将其写入到中excel。

自动获取数据
#

为什么使用影刀
#

相较于影刀,我更多关注了哪些原生支持cli和开源的方案,一方面,支持cli就可以通过agent来自动化获取数据;另一方面,开源方案通常来说本地部署是不需要钱的。 但是后来我在试着根据这个视频来通过claude code调用playwrightcli,但是效果非常差,经常莫名其妙要求人工验证,也不知道哪里出问题了,之后有时间我准备在codex上再试试。 影刀使用还是很方便的,全是拖动节点,手动捕获目标区域。整个就是模拟人类点击滚动等操作,很不容易被封禁。关于费用方面,我目前也没发现他有什么收费的点,好像是多人合作使用一个的时候要付费,等于免费😆

其实可以看到,我这个获取数据还是不是直接整个页面获取的,而是分成了两个获取的步骤,第一个获取相似元素:因为每个商品卡没办法捕获为整体, 而每个商品的标题栏,也就是订单编号和下单时间这一栏,可以捕获,于是我对每个订单的标题栏都采用了获取相似元素列表,最终保存结果为order*heads.csv,这个数据是相对==*干净整洁_==的
但是效果还是不够好,还是会识别出一些乱的文字,如下图
于是我最终还是决定调用大模型来分析和处理这些数据。输入的文件就是这个heads,和fullpage的文件。

本地大模型调用
#

我原本是在使用fastgpt来处理这个数据的,因为fastgpt可以显式的制定大模型的提示词,而且之前那个净水客服我也配置好了相应的大模型供应商。但是后来发现搞来搞去,最后就一个节点😅,于是fastgpt就显得没什么很大的必要了。我最后决定使用openai库来调用大模型处理,话说这应该是我第一次通过代码来本地调用大模型。先看一下main函数:

 1def main() -> int:
 2
 3log("加载环境变量")
 4
 5load_dotenv()
 6parser = argparse.ArgumentParser(description="Call DashScope to generate output.json")
 7parser.add_argument("--prompt", default="prompt.txt", help="prompt file path")
 8parser.add_argument("--heads", default="data/order_heads.csv", help="order heads csv path")
 9parser.add_argument("--full", default="data/order_full.txt", help="full order text path")
10parser.add_argument("--out", default="data/output.json", help="output JSON path")
11parser.add_argument("--model", default=os.getenv("DASHSCOPE_MODEL", DEFAULT_MODEL))
12parser.add_argument("--base-url", default=os.getenv("DASHSCOPE_BASE_URL", DEFAULT_BASE_URL))
13parser.add_argument("--api-key", default=os.getenv("DASHSCOPE_API_KEY"))
14parser.add_argument(
15"--no-json-mode",
16action="store_true",
17help="do not send response_format=json_object to the model API",
18)
19args = parser.parse_args()
20if not args.api_key:
21print("缺少 DASHSCOPE_API_KEY。请先创建 .env,或用 --api-key 传入。", file=sys.stderr)
22return 2
23log("开始生成 output.json")
24result = call_model(
25prompt_path=Path(args.prompt),
26order_heads_path=Path(args.heads),
27order_full_path=Path(args.full),
28model=args.model,
29base_url=args.base_url,
30api_key=args.api_key,
31use_json_mode=not args.no_json_mode,
32)
33out_path = Path(args.out)
34log(f"写入结果文件: {out_path}")
35out_path.write_text(json.dumps(result, ensure_ascii=False, indent=2), encoding="utf-8")
36order_count = len(result.get("orders", [])) if isinstance(result, dict) else 0
37log(f"已生成: {out_path}")
38log(f"订单数量: {order_count}")
39return 0

首先这个main函数很明显的一点就是使用了argparser来解析命令行,分别获取数据文件位置,大模型相关信息(base_url、model、dashborad、api,promot),然后调用call_model这个函数来调用大模型。 在call_model函数中,核心就这些

 1log(f"初始化模型客户端: model={model}, base_url={base_url}")
 2
 3client = OpenAI(api_key=api_key, base_url=base_url)
 4
 5kwargs: dict[str, Any] = {
 6
 7"model": model,
 8
 9"messages": [
10
11{
12
13"role": "system",
14
15"content": "你是订单文本结构化助手。只返回严格 JSON,不要返回 Markdown 或额外说明。",
16
17},
18
19{"role": "user", "content": user_message},
20
21],
22
23"temperature": 0,
24
25}
26
27if use_json_mode:
28
29kwargs["response_format"] = {"type": "json_object"}
30
31
32
33log("开始请求大模型,等待返回...")
34
35start = time.perf_counter()
36
37response = client.chat.completions.create(**kwargs)
38
39elapsed = time.perf_counter() - start
40
41log(f"模型已返回,耗时 {elapsed:.1f} 秒")

然后再对这个输出的json进行一些格式检查,就直接保存到本地了。 输出的json文件如下:

写入excel
#

要求写入的表格如下:

xlsx文件本质是一个压缩包,把不同的sheet压缩到一块。通过python的zipfile可以对xlsx文件进行解压并读取,写入完成后,再通过zipfile对其重新压缩。 对于文件写入,是通过xml.etree.ElementTree这个模块来获得的,展开后的xlsx,本质都是xml结构,即openxml协议。 通过手动查找、增加和修改 XML 标签(例如表示行的 <row> 和表示单元格的 <c> 以及表示值的 <v>)来实现对工作表内容的编辑。 %% 该说不说,在此之前我对xlsx一直都有刻板印象,是一个微软(肯定不是)的封闭的打开很麻烦的一种文件格式,没想到竟然内部也是朴实无华的。 %% 通过这样一套逻辑,也可以成功的把数据写入到指定的行和列。

graph TD
	a[开始] --定时启动--> b[影刀]
	b--数据-->c[大模型]
	c-->d[写入xlsx]

生活
#

最近把公司配的macbook熟络了一下,真香啊,感觉这个屏幕看着就很舒服,其实这个屏幕也不是高刷屏,但好像是什么hdr,反正看着就是很舒服。 除此以外,macos的生态也很好,很多我的linux上没有的软件,macos都支持。 希望以后能有钱买这个电脑