20个群都来问我的AI早报,是这么做的。 * { margin: 0; padding: 0; outline: 0; } body { font-family: “PingFang SC”, system-ui, -apple-system, BlinkMacSystemFont, “Helvetica Neue”, “Hiragino Sans GB”, “Microsoft YaHei UI”, “Microsoft YaHei”, Arial, sans-serif; line-height: 1.6; } .__page_content__ { max-width: 667px; margin: 0 auto; padding: 20px; text-size-adjust: 100%; color: rgba(0, 0, 0, 0.9); padding-bottom: 64px; } .title { user-select: text; font-size: 22px; line-height: 1.4; margin-bottom: 14px; font-weight: 500; } .__meta__ { color: rgba(0, 0, 0, 0.3); font-size: 15px; line-height: 20px; hyphens: auto; word-break: break-word; margin-bottom: 50px; } .__meta__ .nick_name { color: 576B95; } .__meta__ .copyright { color: rgba(0, 0, 0, 0.3); background-color: rgba(0, 0, 0, 0.05); padding: 0 4px; margin: 0 10px 10px 0; } blockquote.source { padding: 10px; margin: 30px 0; border-left: 5px solid ccc; color: #333; font-style: italic; word-wrap: break-word; } blockquote.source a { cursor: pointer; text-decoration: underline; } .item_show_type_0 > section { margin-top: 0; margin-bottom: 24px; } a { color: 576B95; text-decoration: none; cursor: default; } .text_content { margin-bottom: 50px; user-select: text; font-size: 17px; white-space: pre-wrap; word-wrap: break-word; line-height: 28px; hyphens: auto; } .picture_content .picture_item { margin-bottom: 30px; } .picture_content .picture_item .picture_item_label { text-align: center; } img { max-width: 100%; } .pay_subscribe_notice { margin: 30px 0; padding: 20px; background: fffbe6; border: 1px solid ffe58f; border-radius: 8px; } .pay_subscribe_badge { display: inline-block; padding: 4px 12px; background: faad14; color: fff; border-radius: 4px; font-size: 14px; font-weight: 500; margin-bottom: 12px; } .pay_subscribe_desc { font-size: 15px; line-height: 1.8; color: rgba(0, 0, 0, 0.7); margin-bottom: 12px; } .pay_subscribe_hint { font-size: 13px; color: rgba(0, 0, 0, 0.4); } .__bottom-bar__ { display: flex; justify-content: space-between; align-items: center; position: fixed; bottom: 0; left: 0; right: 0; height: 64px; padding: 8px 20px; background: white; box-sizing: border-box; border-top: 1px solid rgba(0, 0, 0, 0.2); } .__bottom-bar__ .left { display: flex; align-items: center; font-size: 15px; white-space: nowrap; } .__bottom-bar__ .right { display: flex; } .__bottom-bar__ .sns_opr_btn { display: flex; align-items: center; user-select: none; background: transparent; border: 0; color: rgba(0, 0, 0, 0.9); font-size: 14px; } .__bottom-bar__ .sns_opr_btn:not(:last-child) { margin-right: 16px; } .__bottom-bar__ .sns_opr_btn > img { margin-right: 4px; }

20个群都来问我的AI早报,是这么做的。

原创 数字生命卡兹克 数字生命卡兹克 2024-10-17 10:44 北京

原文地址: https://mp.weixin.qq.com/s/s-zZkKtjXgNJUQQgAM07Zw

我自己的AI群里,一直有一个传统,就是每天早上,都会发一个AI早报,让群友了解昨天AI圈发生了一些啥大事。

就是这个东西。

从去年到今天,总有群友在问我每天的AI早报是咋做的。

其实吧,在国庆之前呢,都是5群的一个朋友@日不落太阳做的,他每天早上会发到5群里,我每天只是负责转发= =

那时候吧,其实也想着,不能总是依赖别人,这种东西最好还是自己做一个,不能老是麻烦别人。

但是吧,我自己本身就很忙,一来二去,就一直拖拖拖。

然后问题开始在时间的不确定性。有时早上9点就能收到早报,有时却要等到11点之后,早报直接变午报了。群友们的催促声此起彼伏,我只能尴尬地重复着等等= =

压倒我的最后一根稻草是国庆假期。那个早晨,我如往常一样等待日报,却迟迟未收到。

然后联系那位朋友才知道,他去旅游了,时差都快干镜像了,实在是无暇顾及早报。

所以,那天之后,我痛定思痛,决定还是自己来造一个吧。

既然自己做,那肯定不能天天自己手动整理,那也太der了,必定是先抓取各种各样的数据源,然后全自动化的用AI总结。最后人转到群里。

之所以用人不用那种微信机器人,是我怕封号+炸群。

说干就干,我顺藤摸瓜,反向搜索@日不落太阳最后发的内容,并找到尽可能早的信息来源。

然后就找到了一个AIBase.com,信息还挺全的。

仔细观察后发现,这个网站的页面结构很规律,新闻链接都是按数字递增的。

这也太适合抓取了。。。

但是这次我吸取了上次的教训,之前有一期做快手AI短剧评论分析的时候,买了八爪鱼的软件会员,一个月400,然后就没啥用了,后面再用还得开会员,亏死我了。

这次,我就想直接搞个python代码一劳永逸。

我对代码可以说一窍不懂,直懂一点Html和css的基础知识,所以为了搞定这个项目,我先在网上随手找了一个爬虫代码,交给ChatGPT,希望他能按我给的URL修改。

但是,当我满怀期待地放到本地运行它时,就是一顿哐哐报错。。

跟ChatGPT沟通了半天,也搞不定问题,真的愁死我了,还直接给我o1的次数干干净了。

还好当天晚上,天降神兵,我跟朋友简单吐槽了两句后,他给我发了个神器。

Crawl4ai。

就是下面这个star增长像火箭一样的项目。

网址在此:https://github.com/unclecode/crawl4ai

Crawl4ai大大简化了使用抓取内容所需要配置的步骤。

只需要十几行代码就能跑起来一个最简单的项目。

比如下面这个快速开始的示例。

安装也很简单。

只有一行代码。

然后我把特定的一个信息源的文章详情地址替换进去。

牛批起飞,直接能爬下来了。

但是数据展示很混乱,我们肯定希望标题是单独一行,时间是单独一行,内容是单独一行,现在直接糊成一坨了。

我这次实在不想指望AI了,直接求助朋友了。

很快,他就帮我搞定了。

代码我贴在下面了。

import json``import asyncio``from crawl4ai import AsyncWebCrawler``from crawl4ai.extraction_strategy import JsonCssExtractionStrategy`` ``async def extract_ai_news_article():    print("\n--- 使用 JsonCssExtractionStrategy 提取 AIbase 新闻文章数据 ---")``     # 定义提取 schema    schema = {        "name": "AIbase News Article",        "baseSelector": "div.pb-32",  # 主容器的 CSS 选择器        "fields": [            {                "name": "title",                "selector": "h1",                "type": "text",            },            {                "name": "publication_date",                "selector": "div.flex.flex-col > div.flex.flex-wrap > span:nth-child(6)",                "type": "text",            },            {                "name": "content",                "selector": "div.post-content",                "type": "text",              },        ],    }``     # 创建提取策略    extraction_strategy = JsonCssExtractionStrategy(schema, verbose=True)``     # 使用 AsyncWebCrawler 进行爬取    async with AsyncWebCrawler(verbose=True) as crawler:        result = await crawler.arun(            url="https://www.aibase.com/zh/news/12386",  # 替换为实际的目标 URL            extraction_strategy=extraction_strategy,            bypass_cache=True,  # 忽略缓存,确保获取最新内容        )``         if not result.success:            print("页面爬取失败")            return``         # 解析提取的内容        extracted_data = json.loads(result.extracted_content)        print(f"成功提取 {len(extracted_data)} 条记录")        print(json.dumps(extracted_data, indent=2, ensure_ascii=False))``     return extracted_data`` ``# 运行异步函数``if __name__ == "__main__":    asyncio.run(extract_ai_news_article())``

直接跑一波,就可以获得一篇文章的全文内容了。

效果很好,只有一处小bug。

阅读时间和发布时间没有正确显示。

不好意思再麻烦朋友了,我直接把整个网站的Html代码和这段抓取的代码,同时扔给了OpenAI o1,在思考了5秒后,他成功解决了这个错误。

删去一些用不到的内容,下图就是最后的输出效果啦。

有标题,有时间,有内容。非常全面。

爬下来的内容会保存成一个JSON文件。

因为这个还是单个文章的方法,再做一个循环,不断地抓就行。大概做了一个流程图,如果有错勿喷,我是一个纯代码小白。。。

接下来,终于到了我自己能解决的范围里了,就是用AI,来总结这些抓取的内容。

因为每天都要输出,大模型API还是挺重要的,需要便宜,不烧钱,而且毕竟就做个总结而已,我就选了智谱的GLM-4-Air的API,然后写了一个prompt,让模型自动把每条新闻概括成一句话。

这一步非常轻松,一个命令行版的AI日报工具就诞生了。

一般是每天早上8点左右会自动跑一遍程序,来找昨天早上8点到今天早上8点的所有新闻。

每次运行,它就会自动爬取最新新闻,用AI生成概要,然后在命令行里输出结果。

我只需要复制到记事本里稍作排版,一份日报就大功告成了。

看着源源不断涌现的新闻数据,我有种热泪盈眶的感觉。

终于自己把这个小玩意干出来了,可以自己每天跑早报,然后发给群友了。。。

但我很快意识到,这只是开始。

因为每天这新闻也太特么多了。。。

我自己筛选一遍,都特么脑壳大。

然后坏消息总是一起到来,我的“得力助手”AIBase突然没来由的,直接停更了。

行吧。。。

只能又重新找源了。

又找了一段时间,总算是让我找到了一个更新速度飞快的科技新闻网站TechCrunch。

https://techcrunch.com/

然后防止他俩都不靠谱,我又找了几个其他的网站,来扩充我的数据源,甚至还花了2000多大洋买了个The Information和华尔街日报。

现在已经有了5个稳定的英文科技网站和3个中文AI资讯站作为背后的信息源,谁抽风一下,我也不慌了。

每天早上,我只需要打开电脑,运行一下脚本,新鲜出炉的AI新闻就会呈现在我面前。

然而,面对着黑乎乎的命令行界面,我总觉得少了点什么。而且,每次都要人工手动复制到记事本编辑整理,那也太蠢了。

所以,重拾UI老本行,给它加个简单的UI页面吧,命令行界面,我实在扛不住。

我又开始了新一轮的折腾。

首先,我实现了每隔几小时自动爬取一次新闻,并在网页上显示获取到的内容。这下不用我盯着电脑看了,它会自动更新。

但是呢,虽然新闻自动更新了,我还是得手动复制到记事本里编辑。

于是为了把懒逼精神贯彻到底,我又加了个文本框,可以直接在网页上编辑内容复制粘贴了。

可用着用着,我又觉得这个交互逻辑不够顺畅。

因为这还是得我自己复制再粘贴到这个网页的文本框里,还是麻烦。

于是,想了一会,我又把概要做成了一个列表,每条新闻都有个复选框,我可以勾选最新最有趣的内容。它就会自动出现在右边的预览框里,可以实时预览选中的内容。

然后再把编辑的文本框放在下面,根据勾选的内容自动加上日期和序号,再搞个一键复制按钮,完成全傻瓜式AI早报制作。

还顺便做了些小更新。

比如,为了便捷快速的调顺序,又加了个拖动排序功能。

这下可好,鼠标点点选选就能搞定一期日报,再也不用担心被群友们催更了。

而我的电脑呢,就像个尽职尽责的小助手,每小时都会准时去各大网站巡逻一圈,看看有什么新鲜有趣的AI新闻。

丑是稍微丑了点,但是反正自己用,就这样也没事,懒得改了哈哈哈。

再比如,随着时间推移,我的JSON文件越来越大,加载速度也越来越慢。

为了提升用户体验,现学现卖,学着把数据迁移到了数据库,并且每次只加载最新的50条新闻。这下加载速度嗖嗖的,用起来更顺畅了。

经过这段时间的折腾,总算是“人工智能”了。

也能稳定每天早上给群友产出一份AI早报了,目前稳定运行15天,基本上没有出任何岔子。

所以也敢写下这篇文章,算是一个小小的复盘和总结。

人嘛,总是要不断折腾不断尝鲜的。

就像马斯克说的那一句:

成功了,就是进步的一大步。

失败了也无所谓。

**那也会是,**夜空中最璀璨的星光。

以上,既然看到这里了,如果觉得不错,随手点个赞、在看、转发三连吧,如果想第一时间收到推送,也可以给我个星标⭐~谢谢你看我的文章,我们,下次再见。

>/ 作者:卡兹克、东毅、小瑞

>/ 投稿或爆料,请联系邮箱:wzglyay@gmail.com

数字生命卡兹克

![](data:image/svg+xml,%3Csvg xmlns=‘http://www.w3.org/2000/svg’ width=‘24’ height=‘24’ viewBox=‘0 0 24 24’%3E%3C!— Icon from Lucide by Lucide Contributors - https://github.com/lucide-icons/lucide/blob/main/LICENSE —%3E%3Cg fill=‘none’ stroke=‘%23888888’ stroke-linecap=‘round’ stroke-linejoin=‘round’ stroke-width=‘2’%3E%3Cpath d=‘M2.062 12.348a1 1 0 0 1 0-.696a10.75 10.75 0 0 1 19.876 0a1 1 0 0 1 0 .696a10.75 10.75 0 0 1-19.876 0’/%3E%3Ccircle cx=‘12’ cy=‘12’ r=‘3’/%3E%3C/g%3E%3C/svg%3E) 阅读![](data:image/svg+xml,%3Csvg width=‘25’ height=‘24’ viewBox=‘0 0 25 24’ fill=‘none’ xmlns=‘http://www.w3.org/2000/svg’%3E%3Cpath fill-rule=‘evenodd’ clip-rule=‘evenodd’ d=‘M16.154 6.797l-.177 2.758h4.009c1.346 0 2.359 1.385 2.155 2.763l-.026.148-1.429 6.743c-.212.993-1.02 1.713-1.977 1.783l-.152.006-13.707-.006c-.553 0-1-.448-1-1v-8.58a1 1 0 0 1 1-1h2.44l1.263-.03.417-.018.168-.015.028-.005c1.355-.315 2.39-2.406 2.58-4.276l.01-.16.022-.572.022-.276c.074-.707.3-1.54 1.08-1.883 2.054-.9 3.387 1.835 3.274 3.62zm-2.791-2.52c-.16.07-.282.294-.345.713l-.022.167-.019.224-.023.604-.014.204c-.253 2.486-1.615 4.885-3.502 5.324l-.097.018-.204.023-.181.012-.256.01v8.218l9.813.004.11-.003c.381-.028.72-.304.855-.709l.034-.125 1.422-6.708.02-.11c.099-.668-.354-1.308-.87-1.381l-.098-.007h-5.289l.26-4.033c.09-1.449-.864-2.766-1.594-2.446zM7.5 11.606l-.21.005-2.241-.001v8.181l2.45.001v-8.186z’ fill=‘%23000’/%3E%3C/svg%3E) 赞 ![](data:image/svg+xml;charset=utf8,%3Csvg xmlns=‘http://www.w3.org/2000/svg’ width=‘24’ height=‘24’ viewBox=‘0 0 24 24’%3E %3Cg fill=‘none’ fill-rule=‘evenodd’%3E %3Cpath d=‘M0 0h24v24H0z’/%3E %3Cpath fill=‘%23576B95’ d=‘M13.707 3.288l7.171 7.103a1 1 0 0 1 .09 1.32l-.09.1-7.17 7.104a1 1 0 0 1-1.705-.71v-3.283c-2.338.188-5.752 1.57-7.527 5.9-.295.72-1.02.713-1.177-.22-1.246-7.38 2.952-12.387 8.704-13.294v-3.31a1 1 0 0 1 1.704-.71zm-.504 5.046l-1.013.16c-4.825.76-7.976 4.52-7.907 9.759l.007.287c1.594-2.613 4.268-4.45 7.332-4.787l1.581-.132v4.103l6.688-6.623-6.688-6.623v3.856z’/%3E %3C/g%3E%3C/svg%3E) 分享 ![](data:image/svg+xml;charset=utf8,%3Csvg xmlns=‘http://www.w3.org/2000/svg’ xmlns:xlink=‘http://www.w3.org/1999/xlink’ width=‘24’ height=‘24’ viewBox=‘0 0 24 24’%3E %3Cdefs%3E %3Cpath id=‘a62bde5b-af55-42c8-87f2-e10e8a48baa0-a’ d=‘M0 0h24v24H0z’/%3E %3C/defs%3E %3Cg fill=‘none’ fill-rule=‘evenodd’%3E %3Cmask id=‘a62bde5b-af55-42c8-87f2-e10e8a48baa0-b’ fill=‘%23fff’%3E %3Cuse xlink:href=‘%23a62bde5b-af55-42c8-87f2-e10e8a48baa0-a’/%3E %3C/mask%3E %3Cg mask=‘url(%23a62bde5b-af55-42c8-87f2-e10e8a48baa0-b)‘%3E %3Cg transform=‘translate(0 -2.349)‘%3E %3Cpath d=‘M0 2.349h24v24H0z’/%3E %3Cpath fill=‘%23576B95’ d=‘M16.45 7.68c-.954 0-1.94.362-2.77 1.113l-1.676 1.676-1.853-1.838a3.787 3.787 0 0 0-2.63-.971 3.785 3.785 0 0 0-2.596 1.112 3.786 3.786 0 0 0-1.113 2.687c0 .97.368 1.938 1.105 2.679l7.082 6.527 7.226-6.678a3.787 3.787 0 0 0 .962-2.618 3.785 3.785 0 0 0-1.112-2.597A3.687 3.687 0 0 0 16.45 7.68zm3.473.243a4.985 4.985 0 0 1 1.464 3.418 4.98 4.98 0 0 1-1.29 3.47l-.017.02-7.47 6.903a.9.9 0 0 1-1.22 0l-7.305-6.73-.008-.01a4.986 4.986 0 0 1-1.465-3.535c0-1.279.488-2.56 1.465-3.536A4.985 4.985 0 0 1 7.494 6.46c1.24-.029 2.49.4 3.472 1.29l.01.01L12 8.774l.851-.85.01-.01c1.046-.951 2.322-1.434 3.59-1.434 1.273 0 2.52.49 3.472 1.442z’/%3E %3C/g%3E %3C/g%3E %3C/g%3E%3C/svg%3E) 推荐 ![](data:image/svg+xml,%3Csvg width=‘25’ height=‘24’ viewBox=‘0 0 25 24’ fill=‘none’ xmlns=‘http://www.w3.org/2000/svg’%3E%3Cpath d=‘M22.242 7a2.5 2.5 0 0 0-2.5-2.5h-14a2.5 2.5 0 0 0-2.5 2.5v8.5a2.5 2.5 0 0 0 2.5 2.5h2.5v1.59a1 1 0 0 0 1.707.7l1-1a.569.569 0 0 0 .034-.03l1.273-1.273a.6.6 0 0 0-.8-.892v-.006L9.441 19.1l.001-2.3h-3.7l-.133-.007A1.3 1.3 0 0 1 4.442 15.5V7l.007-.133A1.3 1.3 0 0 1 5.742 5.7h14l.133.007A1.3 1.3 0 0 1 21.042 7v4.887a.6.6 0 1 0 1.2 0V7z’ fill=‘%23000’ fill-opacity=’.9’/%3E%3Crect x=‘14.625’ y=‘16.686’ width=‘7’ height=‘1.2’ rx=’.6’ fill=‘%23000’ fill-opacity=’.9’/%3E%3Crect x=‘18.725’ y=‘13.786’ width=‘7’ height=‘1.2’ rx=’.6’ transform=‘rotate(90 18.725 13.786)’ fill=‘%23000’ fill-opacity=’.9’/%3E%3C/svg%3E) 留言