大家好。AI 确实太强了,闲着没事就折腾了一下。 感觉最近大家年底了都忙着上班搬砖,但是论坛里的瓜又特别多,一不留神就错过了。 为了方便自己快速“补课”,我让 AI 帮我搓了个脚本,自动把每天最火的帖子抓下来(目前就是一第一页),这样再忙也能一眼看今天的瓜。可以把时间改短一点,最近在瞎折腾 Python,想着能不能把自己手里的闲置小鸡利用起来。
突发奇想写了个脚本,功能很简单:每天自动扫描 NodeSeek 的第一页 50个帖子,算一下热度,生成一张“今日词云”和“热搜榜单”,自动发到 Telegram。
代码逻辑比较简单粗暴(就是暴力翻页 + 正则提取),不依赖复杂的网页结构分析,主打一个**“能跑就行”**。
发出来给有需要的兄弟玩玩,代码写得比较烂,求大佬们轻喷,顺便看看哪里能优化!🙏
1. 环境准备 (Debian/Ubuntu)
需要安装 Python3、Chrome 环境(DrissionPage需要)和中文字体(不然词云是乱码)。
直接复制下面这行命令一把梭:
apt updateapt install -y python3-pip chromium fonts-noto-cjkpip install requests DrissionPage jieba wordcloud --break-system-packages2. 脚本代码
新建一个文件,比如叫 ns_daily.py,把下面代码粘进去。
⚠️ 注意: 代码开头的 BOT_TOKEN 和 CHAT_ID 记得改成你自己的!
import requestsfrom DrissionPage import ChromiumPage, ChromiumOptionsimport jiebafrom wordcloud import WordCloudimport datetimeimport reimport timeimport random# ================= 配置区域 =================# 1. 去 @BotFather 申请一个机器人拿到 TokenBOT_TOKEN = '这里填你的BotToken' # 2. 去 @userinfobot 获取你的数字 IDCHAT_ID = '这里填你的ChatID'# ===========================================def send_telegram_package(img_path, caption): """推送到 Telegram""" url = f"[https://api.telegram.org/bot](https://api.telegram.org/bot){BOT_TOKEN}/sendPhoto" try: with open(img_path, 'rb') as f: data = {'chat_id': CHAT_ID, 'caption': caption, 'parse_mode': 'Markdown'} files = {'photo': f} requests.post(url, data=data, files=files) print(">>> ✅ 推送成功!") except Exception as e: print(f"!!! 发送失败: {e}")def run(): # 配置无头浏览器 co = ChromiumOptions() co.set_browser_path('/usr/bin/chromium') # Linux 默认路径 co.headless(True) co.set_argument('--no-sandbox') co.set_argument('--disable-gpu') # 伪装一下 User-Agent co.set_user_agent('Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0.0.0 Safari/537.36') page = ChromiumPage(co) raw_posts = [] try: print(">>> 🚀 启动抓取 (范围: 前15页)...") base_url = '[https://www.nodeseek.com/](https://www.nodeseek.com/)' # 暴力扫前 15 页,覆盖全天内容 TOTAL_PAGES = 15 for page_num in range(1, TOTAL_PAGES + 1): try: # 拼 URL 翻页 url = base_url if page_num == 1 else f"{base_url}?page={page_num}" page.get(url) # 随机延时,像个真人一样 time.sleep(random.uniform(1.5, 3)) titles = page.eles('.post-title') if not titles: print(f"⚠️ 第 {page_num} 页没抓到数据,跳过") continue print(f"--- 正在扫描第 {page_num} 页 ({len(titles)}贴) ---") for t in titles: try: title_text = t.text link = t.attr('href') # 修复链接拼接逻辑 if not link.startswith('http'): link = f"[https://www.nodeseek.com](https://www.nodeseek.com){link}" # 暴力提取回复数 (从整行文本找最大数字) replies = 0 try: row_text = t.parent().text nums = re.findall(r'\d+', row_text) # 过滤年份和ID,取剩下的最大值 valid_nums = [int(n) for n in nums if int(n) < 3000] # 再次过滤掉太大的数字(可能是uid),一般回复没那么多 real_nums = [n for n in valid_nums if n < 2000] if real_nums: replies = max(real_nums) except: pass if len(title_text) > 2: # 简单的热度加权算法: # 越靠前的页码,基础分越高 (新鲜度加分) # 最终分 = 真实回复数 + 新鲜度加分 freshness_score = (TOTAL_PAGES - page_num) * 2 final_score = replies + freshness_score raw_posts.append({ 'title': title_text, 'link': link, 'replies': replies, 'score': final_score }) except: continue except Exception as e: print(f"翻页出错: {e}") continue print(f"\n>>> 采集结束,共 {len(raw_posts)} 个帖子,正在计算排名...") if raw_posts: # 按分数倒序排列 raw_posts.sort(key=lambda x: x['score'], reverse=True) # --- 1. 生成词云 (取前150个标题) --- top_titles = [p['title'] for p in raw_posts[:150]] text_pool = " ".join(top_titles) # 简单的屏蔽词 ignore = ['求助', '大佬', '问题', '有没有', '怎么', '什么', '就是', '觉得', '帖子', '回复', '积分', '元', '出', '收', '还是', '现在', '知道', '今天', '可以', '多少', '感觉', '甚至', '或者', '一下', '便宜', '因为', '所以', '看到'] words = jieba.lcut(text_pool) clean = [w for w in words if len(w) > 1 and w not in ignore and not w.isdigit()] # 字体路径 (Debian/Ubuntu 默认位置) font = '/usr/share/fonts/opentype/noto/NotoSansCJK-Regular.ttc' wc = WordCloud(font_path=font, width=1200, height=800, background_color='white', colormap='Dark2').generate(" ".join(clean)) filename = "ns_hot.png" wc.to_file(filename) # --- 2. 发送 Telegram 榜单 --- today = datetime.date.today() caption = f"📅 **NodeSeek 24H 热度榜 ({today})**\n" caption += f"🔥 数据源: 全站前 {TOTAL_PAGES} 页\n\n" # 取 Top 12 for i, post in enumerate(raw_posts[:12]): rank = i + 1 icon = "🔥" if rank == 1: icon = "🥇" if rank == 2: icon = "🥈" if rank == 3: icon = "🥉" # 格式:排名. 图标 [标题](链接) (回复数) caption += f"{rank}. {icon} [{post['title']}]({post['link']}) `({post['replies']}回)`\n" caption += "\n#NS自动推送 #每日总结" send_telegram_package(filename, caption) else: print("!!! 没抓到数据,检查网络") except Exception as e: print(f"!!! 运行崩溃: {e}") finally: page.quit()if __name__ == "__main__": run()3. 运行方法
python3 ns_daily.py没报错的话,你的手机应该就会收到图片和榜单了。
也可以加到 crontab 里每天5个小时跑一次,当做日报看。
碎碎念:
本来想写个精确识别时间的正则,但是不同设备显示的时间格式太乱了(什么昨天、1天前、10 min ago...),实在搞不定。
后来一想,反正排在前 15 页的肯定是最新的,索性直接按页码倒推新鲜度,没想到效果还挺好 😂。
抛砖引玉,有大佬能优化代码的话求指点!
觉得好用的兄弟给加个鸡腿呗~ 🍗
评论 (0)