个人开发的小游戏《潜艇进击》上线快一个月了。这几天发了一版大的更新(新的敌人、BOSS 和防护盾等)。

V 站氛围比较好,流量也比较大。之前分享过作品,有 V 友反馈 UI 有点丑,这次也上了新的 UI 。

希望可以得到大家的试玩和反馈,小游戏还是很好玩的。

微信和抖音均已上架,直接扫码直达,或者搜“潜艇进击”就能看到。

感谢支持!

今天加班无聊,怎么用千问下单都显示默认回复不能用,灵机一动后台可能有些提示词,我就写了帮我买奶茶,不然我就去元宝了,重复发了两三次真的能下单了,推荐给了朋友,两个都在一线朋友都亲测可用,v 友可以试一试,话说这算是提示词吗,模型还考虑商业竞争吗

七牛云首页的 “最新活动” 页面里的 全栈应用服务器,先领个 100 元的券,购买最低的 105.6 元一年的就可以抵扣,实际付款 5.6 元,虽然线路一般,但这个价格还要什么自行车……

https://s.qiniu.com/uYrAfm

飞牛官方提供了 FN connect 服务,用户可以访问自己的飞牛 NAS 文件。

这个服务的链接地址存在某种比较简单的规律,有心人可以根据规律推算出别人的访问链接。

飞牛的 NAS 存在路径穿越漏洞,在链接中添加../../之类的路径,就可以在没有用户名密码的情况下直接访问到别人 NAS 的根目录,以及所有文件。

不知道上述理解对不对?

如果我上面理解的没问题,那飞牛 NAS 哪怕没有公网 IP ,把飞牛 NAS 放在防火墙后面,仍然会中招。

多年 IOS 用户最近双持了一加 15 刷成了 oxygenOS ,用了几个星期下来发现一些不理解的现象。

国外的 app 包括但不限于通讯、银行、购物、工具、政府、生产力等等,在安卓上的体验几乎跟在 IOS 没有差别,有的甚至更顺手,比如我常用的二手平台 Carousell ,还有 meta 、亚马逊等各家大厂的 app 也是用起来很顺手。

唯独国产的 App 不知道怎么就是比 IOS 要难用,不跟手,逻辑混乱,界面字体大小混乱,是做不到吗还是不想做?

RT, 公司发了个新 mac, 用了 5 年的 m1 可以退役了, 很久没有 setup 新 mac 了, 请问大家现在这个年代 mac 有什么必备的软件吗? 我过去习惯 iterm2 这一套了. 谢谢大家!

github: https://github.com/Peiiii/EchoNote (求个 star)
网站: https://stillroot.app (寓意: 让自己随着笔记里的思绪在安静中不断成长)

功能应该说很丰富,欢迎来探索,有的地方还需要完善,也希望大家可以提出批评意见。

这里列几个不容易发现的功能点

  • 支持类似 typora 的 markdown 所见即所得编辑,支持 mermaid 画图
  • 笔记是空间分隔的
  • 支持搜索,可以空间内,也支持全局
  • 长内容会自动收起,对长内容特别友好
  • 追加笔记可以跨设备实时同步,类似通信软件
  • 每条笔记支持灵感功能,可以一键给每条笔记生成 3-5 条灵感
  • 支持把空间分享给它人,目前有两种模式:1.只读,2.可追加(有点类似群聊)
  • 支持让 AI 通过 API 访问,可以一键复制提示词给 AI
  • 自带的 Agent 感知的范围有多种模式可以切换,可以选择任意空间或全部空间
  • Agent 可以读、写、搜索笔记
  • AI Studio: 类似 notebooklm ,可以生成语音播客、思维导图、报告、概念卡片等,还可以打电话(功能还在开发)

当前版本最佳使用场景:碎片化记录想法,不同类别放到不同空间,和 AI 交流想法辅助决策等,讨论出成果了就让 AI 记录成一条笔记(可选:让 AI 带上讨论的时间、背景等原数据标记)。

如果关注的朋友多的话,打算出一个桌面端数据存在本地,这样对接本地的 Agent 更方便。

假设要学习一门计算机课程, 例如 CS 164 或者 CS 110L, 有朋友来分享一下现阶段的 AI 工具生成笔记的最佳实践吗?

我之前在没有 AI 辅助时的做法:

  1. 把课程的 Lectures/Slides/Homework/Assignments 原版英文材料转换成 markdown 格式笔记文件, 创建一个 github 仓库同步.
  2. 对教程视频使用 whisper 模型生成英文字幕.
  3. 在看课程视频和做 Homework 或者 Assignments 的时候对照着 markdown 格式的笔记增加自己的理解和附注, 将视频中的关键图示截图或者做 Assignments 时的关键思路插入笔记中.

这样做的好处是可以最大程度信任自己的笔记内容, 因为这些信息要么是课程原版, 要么是经过自己测试验证过的. 这样一来就可以作为自己的高可信度知识库材料, 以后就可以随时检索, 不用费心分辨大模型给出的可能有误的信息.

但这种方式的最大缺点是会花费非常多的时间在笔记整理上. 例如一节课程大约是 1 到 1.5 小时, 如果要产出完全覆盖视频内容且包括视频中所有关键图示的笔记文件, 差不多需要 3-5 倍的时间. 所以我就想是否能让 AI 来解决这个整理笔记的体力劳动过程, 把更多时间投入到思考概念和解决方案中.

现在遇到的问题是, 我试过的一些现有的云端 AI 工具 (例如 NoteBookLM) 都只是基于视频的字幕文件或者视频的语音来生成笔记内容, 几乎没有视频的图像信息, 因此也就无法将视频中的关键图示插入笔记中. NoteBookLM 可以做到上传课程材料和视频文件, 然后向他提问概念, 但是做不到完整提取视频信息并生成笔记文件. 对于长度超过 1 小时的单个章节课程视频, 云端工具也是大概率不支持一次性或者分段处理的.

不知道有没有利用开源模型来完成这种从课程材料和课程视频生成非常详尽的图文笔记的开源项目? 实在没有的话只能自己动手写一个试试了, 目前的思路是用 qwen3:14b + glm-ocr/deepseek-ocr + ffmpeg 来实现,但是估计以我手上能用的硬件(Tesla P40)跑到冒烟才能跑完一个视频的内容.

打开 ide ,浏览器,有时候很明显动画都没那么流畅

在 goland 里编辑甚至会有卡顿延迟。。。服气的,32g 的版本,内存也没用到顶

用了 5 年 VS Code ,今天还是把它卸了。现在插件是真的多到飞起,占内存不说,打开个项目都能感到明显变慢,已经完全没有当年那种轻快感了。

Cursor 这种把 AI 原生融进编辑器里的,才更像是 2026 年该有的形态;至于 Vim / Neovim 只有在黑窗口里敲字的时候,我才能重新进入那种纯粹的心流。

我一直有个很主观的看法:如果一个程序员连基本快捷键都记不住,每天全靠鼠标点来点去,那效率上限大概率不会太高。

来吧,晒晒你们现在的编辑器配置。还有多少人还在死磕 Vim / Neovim ?

多个相同 hook ,一个 accept ,后面的还执行吗?

chatgpt 和 grok 说 accept 就终结了,gemini 说还能继续执行

chatgpt 回答

grok 回答

gemini 回答

规则 1 ,不同优先级

table inet A {
  chain input {
    type filter hook input priority 0;
    tcp dport 22 accept
  }
}


table inet B {
  chain input {
    type filter hook input priority 10;
    tcp dport 22 drop
  }
} 

规则 2 ,相同优先级

table inet A {
  chain input {
    type filter hook input priority 0;
    tcp dport 22 accept
  }
}


table inet B {
  chain input {
    type filter hook input priority 0;
    tcp dport 22 drop
  }
}

发现两个问题,不知道群友有没有解决方案。

  1. 从美国发起的网络请求(比如 http )无法到达国内电信家庭网络里的主机,TCP 和 UDP 都不 work ,仅测过 ipv6 ,BTW ,可以 ping 通
  2. 从国内发起并建立跟美国的 TCP 连接,下载( us->cn )速度很慢( 50KB ),上传( cn->us )速度还可以( 7MB )


                “Linux之父把AI泡沫喷了个遍”思维导图

“Linux之父把AI泡沫喷了个遍”思维导图模板获取链接

一、核心主题确定

确定核心主题为“Linux之父把AI泡沫喷了个遍”,围绕这一主题,收集和整理Linux之父Linus Torvalds对AI的看法、AI的发展现状、优缺点、炒作周期、分类与作用、未来预测等相关内容,形成思维导图的核心内容框架。

二、导图结构设计

  1. 博文核心观点:作为思维导图的主要分支,涵盖对AI炒作的态度、AI发展现状、AI的优点、AI炒作周期分析、AI的分类与作用、AI的未来预测六个子分支,每个子分支下再细分具体观点和内容。
  2. 博文观点分析:对博文核心观点进行合理性及局限性两方面的分析,每个方面下再细分具体分析内容,形成逻辑严密的论证结构。
  3. 个人观点补充:包含对AI炒作的理解以及对AI未来发展的期待两个子分支,每个子分支下同样细分具体观点,展现个人对AI领域的深入思考。

三、导图样式设计

  1. 颜色搭配:采用绿色作为背景色,给人清新、科技感的视觉感受;不同层级的文字和分支使用不同颜色进行区分,如核心主题用黑色加粗字体,一级分支用深绿色背景白色字体,二级及以下分支用浅绿色背景黑色字体保持视觉一致性。可借鉴图形天下思维导图提供的17套配色方案,选择适合科技主题的配色,增强视觉吸引力。
  2. 形状布局:整体采用树状表格布局,从核心主题向右侧延伸出主要分支,各分支下的子内容以列表形式呈现,层次分明,逻辑清晰。图形天下思维导图提供的12类42种图形布局,可根据内容特点灵活选择,使布局更加专业和有条理。
  3. 字体和字号:选择简洁易读的字体,核心主题字号最大,一级分支字号次之,二级及以下分支字号相对较小,通过字号大小体现内容的层级关系。

“Linux之父把AI泡沫喷了个遍”思维导图模板在线免费体验链接

四、导图工具与流程

  • 工具选择:使用图形天下思维导图软件,该软件不仅提供了丰富的模板、图标、颜色设置等功能,还支持多模态AI生成思维导图,能极大提升创作效率。
  • 创作流程

    • 收集资料:查阅Linus Torvalds关于AI的相关言论、报道以及AI领域的发展现状、技术分析等资料。
    • 整理内容:对收集到的资料进行整理和归纳,提取关键信息,形成各个分支下的具体内容。
    • 创建导图:在图形天下思维导图软件中,先输入核心主题,然后依次创建一级分支、二级分支等。
    • 样式调整:利用软件的树型表格布局,将博文核心观点下的各子分支及其内容以表格形式清晰呈现。同时,利用软件提供的17套配色方案对导图的颜色进行调整。
    • 检查完善:检查导图内容是否完整、逻辑是否连贯、有无错别字等,对不足之处进行修改和完善。

图形天下思维导图软件免费下载链接

五、总结

在本次思维导图的创作过程中,通过运用图形天下思维导图软件的树型表格布局,成功将复杂的内容以清晰、有条理的方式呈现出来。同时,借助软件提供的配色方案预设风格,使导图在视觉上更加吸引人。整个创作流程高效顺畅,充分展现了图形天下思维导图软件在知识管理和思维可视化方面的强大能力。

访问图形天下思维导图模板库教程资源,获取更多免费导图素材与实操指南,激发你的无限创意。

最近入职了一家公司几个月,和一个美女关系不错,经常会两个人聊天。

有一天中午,我俩在茶水间,她让我帮忙和她一起抢演唱会门票。

我心里就顿时有种抵触,不晓得为啥,但是还是帮忙了。

过了一周,我因为突发事件离职,我俩还是有联系。

然后又让我帮她抢演唱会门票。

我心里就非常不舒服。。。

我其实一直没搞懂,为什么我非常不喜欢帮别人抢演唱会的门票,但是别的忙我也愿意帮,就单独抢门票这件事。。。

1. Scrapy的概览与核心价值

想象一下,如果你需要从成千上万个网页中提取结构化数据,用传统的requests + BeautifulSoup方式就像用勺子挖土——虽然可行,但效率低下且难以维护。Scrapy正是为解决大规模、高性能数据抓取需求而生的工业级爬虫框架。

在Python生态系统中,Scrapy占据了不可替代的地位。它不仅仅是一个爬虫库,更是一个完整的爬虫开发框架,将数据抓取的整个流程——从请求调度、网页下载、数据提取到持久化存储——封装成了一套标准化的流水线系统。这种模块化设计让开发者能够专注于"爬什么"而非"怎么爬",极大提升了开发效率。

Scrapy的独特价值在于其基于Twisted异步网络框架的事件驱动架构,能够以单线程实现高并发请求处理,在不增加硬件资源的前提下获得10倍于传统爬虫的抓取速度。同时,它内置的请求去重、自动重试、用户代理轮换等反爬机制,让开发者能够快速构建稳定可靠的爬虫系统。

2. 环境搭建与"Hello, World"

安装Scrapy

Scrapy支持Python 3.7及以上版本,推荐使用Python 3.8+以获得最佳兼容性。安装方式如下:

# 使用pip安装(推荐使用国内镜像源加速)
pip install scrapy -i https://pypi.douban.com/simple

# 验证安装是否成功
scrapy version

如果看到类似Scrapy 2.11.0的版本号输出,说明安装成功。对于Windows用户,可能需要先安装Microsoft Visual C++ Build Tools以解决某些依赖包的编译问题。

第一个Scrapy爬虫

让我们创建一个最简单的爬虫来抓取quotes.toscrape.com网站的励志名言:

import scrapy

class QuotesSpider(scrapy.Spider):
    # 爬虫的唯一标识符
    name = 'quotes'
    
    # 起始URL列表
    start_urls = ['http://quotes.toscrape.com/page/1/']
    
    def parse(self, response):
        # 遍历页面中的每个名言
        for quote in response.css('div.quote'):
            # 提取名言内容、作者和标签
            yield {
                'text': quote.css('span.text::text').get(),
                'author': quote.css('small.author::text').get(),
                'tags': quote.css('a.tag::text').getall(),
            }
        
        # 查找下一页链接并继续爬取
        next_page = response.css('li.next a::attr(href)').get()
        if next_page is not None:
            yield response.follow(next_page, callback=self.parse)

代码逐行解析:

  • class QuotesSpider(scrapy.Spider): 继承Scrapy的Spider基类,所有自定义爬虫都必须这样做
  • name = 'quotes': 定义爬虫名称,运行爬虫时会用到这个标识符,必须在项目中唯一
  • start_urls = [...]: 定义爬虫的起始URL列表,Scrapy会自动为每个URL创建请求
  • def parse(self, response): 默认的回调函数,处理响应的函数名固定为parse(除非你指定其他回调)
  • response.css(...): 使用CSS选择器提取数据,Scrapy支持CSS和XPath两种选择器
  • yield {...}: 生成字典数据,这些数据会被传递给Item Pipeline进行后续处理
  • response.follow(): 创建新的请求来跟进链接,第一个参数是URL,第二个参数是回调函数

运行结果:

在终端中执行以下命令运行爬虫:

scrapy crawl quotes -o quotes.json

运行后,Scrapy会自动从第一页开始抓取,提取每条名言的信息,并自动翻页直到抓取完所有页面。最终数据会保存在quotes.json文件中,格式如下:

[
    {
        "text": "“The world as we have created it is a process of our thinking. It cannot be changed without changing our thinking.”",
        "author": "Albert Einstein",
        "tags": ["change", "deep-thoughts", "thinking", "world"]
    },
    ...
]

3. 核心概念解析

Scrapy的核心架构围绕几个关键组件展开,理解这些组件的职责和交互方式是掌握Scrapy的关键。

3.1 Spider(爬虫)

Spider是用户编写的核心逻辑模块,定义了:

  • 如何爬取网站(起始URL、如何跟进链接)
  • 如何解析页面内容(提取数据)
  • 如何处理提取到的数据(生成Item或新的Request)

每个Spider必须继承scrapy.Spider基类,并至少实现parse()方法。Spider的典型工作流程是:接收Response对象 → 解析页面 → 提取数据或生成新Request → yield出去。

3.2 Item(数据项)

Item是Scrapy提供的数据容器,类似于Python字典但提供了字段验证功能。通过预定义数据结构,Item能够避免字段拼写错误和类型混乱。

import scrapy

class QuoteItem(scrapy.Item):
    text = scrapy.Field()
    author = scrapy.Field()
    tags = scrapy.Field()

使用Item的好处包括:

  • 字段定义清晰,便于团队协作
  • 支持数据验证和类型检查
  • 与Pipeline配合,实现数据清洗的标准化流程

3.3 Pipeline(管道)

Pipeline负责处理Spider提取的Item,典型操作包括:

  • 数据清洗(去除空格、转换格式)
  • 数据验证(检查必填字段)
  • 数据去重(避免重复存储)
  • 持久化存储(存入数据库或文件)
class CleanPipeline:
    def process_item(self, item, spider):
        # 去除文本首尾空格
        item['text'] = item['text'].strip()
        return item

class DatabasePipeline:
    def __init__(self):
        self.db_conn = None
    
    def open_spider(self, spider):
        # 爬虫启动时建立数据库连接
        self.db_conn = create_database_connection()
    
    def process_item(self, item, spider):
        # 将item存入数据库
        self.db_conn.insert(item)
        return item
    
    def close_spider(self, spider):
        # 爬虫关闭时释放资源
        self.db_conn.close()

核心组件关系图

graph TD
    A[Spider] -->|生成Request| B[Engine]
    B -->|传递Request| C[Scheduler]
    C -->|返回待爬Request| B
    B -->|传递Request| D[Downloader]
    D -->|返回Response| B
    B -->|传递Response| A
    A -->|yield Item| B
    B -->|传递Item| E[Pipeline]
    A -->|yield新Request| B
    E -->|处理Item| F[Database/File]
    
    style A fill:#e1f5ff
    style B fill:#fff4e1
    style C fill:#ffe1e1
    style D fill:#e1ffe1
    style E fill:#f0e1ff

Scrapy的工作流程是一个闭环:Spider生成初始Request → Engine调度 → Scheduler排队 → Downloader下载 → Engine传递响应 → Spider解析 → 提取数据或生成新Request → 循环往复。

4. 实战演练:解决一个典型问题

让我们通过一个完整的项目来实战Scrapy的核心功能。我们将爬取豆瓣电影Top250的信息,包括电影名称、评分、导演和简介。

需求分析

目标网站:https://movie.douban.com/top250
需要提取的数据:电影标题、评分、导演、简介
特殊需求:实现翻页功能,爬取所有250部电影

方案设计

选择Scrapy的原因:

  • 高效的异步并发能力,能够快速爬取25页数据
  • 内置的Request去重机制,避免重复爬取
  • 灵活的Pipeline设计,便于数据清洗和存储

技术方案:

  • 使用CSS选择器提取数据
  • 通过翻页链接的规律实现自动翻页
  • 将数据保存为CSV文件便于后续分析

代码实现

步骤1: 创建项目

scrapy startproject douban_movie
cd douban_movie

步骤2: 定义数据结构(items.py)

import scrapy

class MovieItem(scrapy.Item):
    title = scrapy.Field()    # 电影标题
    rating = scrapy.Field()   # 评分
    director = scrapy.Field() # 导演
    intro = scrapy.Field()    # 简介

步骤3: 编写爬虫(spiders/movie_spider.py)

import scrapy
from douban_movie.items import MovieItem

class MovieSpider(scrapy.Spider):
    name = 'douban_top250'
    allowed_domains = ['douban.com']
    start_urls = ['https://movie.douban.com/top250']
    
    def parse(self, response):
        # 提取当前页的所有电影条目
        movie_list = response.css('ol.grid_view li')
        
        for movie in movie_list:
            item = MovieItem()
            
            # 提取电影标题(可能存在中英文名,取第一个)
            item['title'] = movie.css('span.title::text').get()
            
            # 提取评分
            item['rating'] = movie.css('span.rating_num::text').get()
            
            # 提取导演信息
            info = movie.css('div.bd p::text').getall()
            if info:
                director_info = info[0].strip()
                # 导演信息格式:导演: 张三 主演: 李四 王五
                item['director'] = director_info.split('主演:')[0].replace('导演:', '').strip()
            
            # 提取简介(可能不存在)
            item['intro'] = movie.css('span.inq::text').get() or '暂无简介'
            
            yield item
        
        # 处理翻页
        next_page = response.css('span.next a::attr(href)').get()
        if next_page:
            yield response.follow(next_page, callback=self.parse)

步骤4: 配置settings.py

# 模拟浏览器User-Agent
USER_AGENT = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36'

# 不遵守robots协议(豆瓣的robots.txt禁止爬取)
ROBOTSTXT_OBEY = False

# 下载延迟,避免被封IP
DOWNLOAD_DELAY = 2

# 启用Pipeline
ITEM_PIPELINES = {
    'douban_movie.pipelines.DoubanMoviePipeline': 300,
}

运行说明

执行以下命令启动爬虫:

scrapy crawl douban_top250 -o movies.csv

运行过程中你会看到类似以下的日志输出:

2024-06-15 10:00:00 [scrapy.core.engine] INFO: Spider opened
2024-06-15 10:00:02 [scrapy.core.engine] DEBUG: Crawled (200) <GET https://movie.douban.com/top250>
2024-06-15 10:00:04 [scrapy.core.engine] DEBUG: Crawled (200) <GET https://movie.douban.com/top250?start=25&filter=>
...
2024-06-15 10:01:30 [scrapy.statscollectors] INFO: Closing spider (finished)

爬取完成后,movies.csv文件将包含所有250部电影的信息:

title,rating,director,intro
肖申克的救赎,9.7,导演: 弗兰克·德拉邦特,希望让人自由。
霸王别姬,9.6,导演: 陈凯歌,风华绝代。
阿甘正传,9.5,导演: 罗伯特·泽米吉斯,人生就像一盒巧克力。
...

整个爬取过程大约需要1-2分钟,相比传统串行爬虫速度提升了数倍。Scrapy自动处理了并发、去重、重试等复杂问题,让我们能够专注于数据提取逻辑本身。

5. 最佳实践与常见陷阱

5.1 常见错误及规避方法

错误1: 覆盖parse方法导致CrawlSpider失效

# ❌ 错误做法
class MySpider(CrawlSpider):
    name = 'my_spider'
    rules = [Rule(LinkExtractor(), callback='parse')]
    
    def parse(self, response):
        # 自定义parse方法会覆盖CrawlSpider的内置逻辑
        pass
# ✅ 正确做法
class MySpider(CrawlSpider):
    name = 'my_spider'
    rules = [Rule(LinkExtractor(), callback='parse_item')]
    
    def parse_item(self, response):
        # 使用不同的回调函数名
        pass

错误2: 忘记返回Item导致Pipeline无法接收数据

# ❌ 错误做法
def process_item(self, item, spider):
    self.db.insert(item)
    # 忘记返回item,后续Pipeline无法接收到数据
# ✅ 正确做法
def process_item(self, item, spider):
    self.db.insert(item)
    return item  # 必须返回item或抛出DropItem

错误3: 直接修改Request的meta中保留键

# ❌ 错误做法
yield scrapy.Request(url, callback=self.parse, meta={'redirect_urls': [...]})
# ✅ 正确做法
yield scrapy.Request(url, callback=self.parse, meta={'custom_data': {...}})
# 避免使用Scrapy保留的meta键名,如redirect_urls、cookiejar等

5.2 最佳实践建议

1. 合理设置下载延迟

# 根据目标网站的负载能力调整延迟
DOWNLOAD_DELAY = 2  # 对于豆瓣这样的网站,2秒较为合理
AUTOTHROTTLE_ENABLED = True  # 启用自动限速

2. 使用Item Loader简化数据提取

from scrapy.loader import ItemLoader

def parse(self, response):
    loader = ItemLoader(item=MovieItem(), response=response)
    loader.add_css('title', 'span.title::text')
    loader.add_css('rating', 'span.rating_num::text')
    yield loader.load_item()

3. 配置日志级别便于调试

# 开发环境使用DEBUG级别
LOG_LEVEL = 'DEBUG'

# 生产环境使用INFO或WARNING级别
LOG_LEVEL = 'INFO'

4. 使用管道链处理复杂数据流

ITEM_PIPELINES = {
    'myproject.pipelines.ValidationPipeline': 100,  # 数据验证
    'myproject.pipelines.DeduplicationPipeline': 200,  # 去重
    'myproject.pipelines.StoragePipeline': 300,  # 存储
}

5.3 注意事项

  • 遵守robots协议:虽然可以设置ROBOTSTXT_OBEY = False,但建议尽量遵守网站的robots.txt规定,做一个文明的爬虫
  • 控制并发数:默认并发数为16,对于小型网站建议降低到8或更低,避免给服务器造成过大压力
  • 处理异常:在parse方法中使用try-except捕获异常,避免个别页面解析失败导致整个爬虫中断
  • 善用Scrapy Shell:使用scrapy shell URL命令调试选择器,确保提取逻辑正确后再写入爬虫代码
  • 监控爬虫状态:使用Scrapy提供的stats collector监控爬虫运行状态,及时发现异常

6. 进阶指引

掌握了Scrapy的基础用法后,你可以继续探索以下高级特性:

1. 中间件(Middleware)
中间件提供了在请求/响应处理过程中插入自定义逻辑的钩子。典型应用场景包括:

  • 动态切换User-Agent和代理IP
  • 实现请求重试和异常处理
  • 修改请求头和响应内容

2. 分布式爬虫
通过scrapy-redis扩展,可以实现分布式爬虫,多个爬虫节点共享同一个Redis队列,协同处理大规模爬取任务。

3. 动态网页渲染
对于需要JavaScript渲染的页面,可以集成scrapy-splashscrapy-playwright,实现动态内容的抓取。

4. 数据存储扩展
除了CSV和JSON,Scrapy Pipeline可以轻松对接各种数据库:

  • MySQL/PostgreSQL:使用pymysqlpsycopg2驱动
  • MongoDB:使用pymongo驱动
  • Redis:使用redis驱动

学习资源推荐:

  • 官方文档:https://docs.scrapy.org - 最权威和全面的学习资料
  • GitHub仓库:https://github.com/scrapy/scrapy - 查看源码和提交问题
  • Stack Overflow:搜索scrapy标签,解决具体问题
  • 实战项目:尝试爬取不同类型的网站(电商、新闻、社交媒体),积累实战经验

Scrapy的学习曲线虽然略陡,但一旦掌握,你就拥有了构建高性能爬虫系统的强大工具。从简单的数据采集到复杂的分布式爬虫,Scrapy都能胜任。开始你的Scrapy之旅吧!

各位 V 友,大家好。

我一直觉得“买课容易学完难”。过去一年,为了提升自己,我花了不少钱在各种独立开发、SEO 和商业实战的内容上。但时间久了发现,如果不把这些知识内化并输出,它们很快就会变成收藏夹里的灰尘。

所以我最近上线了一个名为 LuckyHYP Hub 的项目。我的思路是:通过二次学习和实践,把学到的精华以分享的方式整理出来。

项目初心:
我想打造一个纯粹的学习空间。把那些零散的、高价的知识体系,经过我的实践验证和逻辑重构后,免费分享给社区里同样在路上的朋友。

为什么值得一看?

  • 全站默认免费:大部分经过我深度重构、带有个人见解的高质量内容都是直接开放阅读的。
  • 极致阅读体验:基于 Next.js 16 + Tailwind 4 打造,全站深色模式 + 玻璃拟态设计,无广告,只为沉浸式学习。
  • 实战导向:不只是简单的搬运,更多的是我按照课程逻辑跑通后的 SOP 总结和个人心得。

关于付费墙(版权保护说明):
在浏览过程中,你可能会发现极少数深度内容设置了“访问门槛”。这主要是为了规避版权风险。因为部分内容涉及到原课程的一些核心保密细节或敏感素材,为了保护原作者利益,我通过这种方式设置了一道准入机制。建议大家优先看站内的免费文章,已经足够丰富了。

项目地址https://luckyhyp.com

想听听大家的建议:

  1. 这种“学习笔记 Hub”的形式,大家是更看重内容的体系化程度,还是更看重实战案例?
  2. 如果内容涉及到敏感版权,除了“设置访问门槛”,大家还有什么既能分享又能保护原作者的好办法吗?

欢迎各位大佬指点吐槽,也希望这些笔记能帮到正在学习相关领域的朋友。

CentOS 7 老树开新花:从零部署 Dify 全栈应用(含 Go/Rust/GCC 升级避坑)

本文档适用于在 CentOS 7 环境下使用源代码部署 Dify 应用,对应版本 1.9.2。由于系统较旧,部分依赖需手动升级或通过容器化方式解决兼容性问题。

一、安装与配置 Docker

1. 卸载旧版本 Docker(如有)

sudo yum remove docker \
                  docker-client \
                  docker-client-latest \
                  docker-common \
                  docker-latest \
                  docker-latest-logrotate \
                  docker-logrotate \
                  docker-engine

2. 安装必要依赖

sudo yum install -y yum-utils device-mapper-persistent-data lvm2

3. 添加 Docker 官方 YUM 源

sudo yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo

4. 安装 Docker Engine 及相关组件

sudo yum install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin

5. 启动并设置开机自启

sudo systemctl start docker
sudo systemctl enable docker

6. 配置国内镜像加速器

<!-- more -->

创建 /etc/docker/daemon.json 文件:

sudo tee /etc/docker/daemon.json <<-'EOF'
{
  "registry-mirrors": [
    "https://docker.registry.cyou",
    "https://docker-cf.registry.cyou",
    "https://dockercf.jsdelivr.fyi",
    "https://docker.jsdelivr.fyi",
    "https://dockertest.jsdelivr.fyi",
    "https://mirror.aliyuncs.com",
    "https://dockerproxy.com",
    "https://mirror.baidubce.com",
    "https://docker.m.daocloud.io",
    "https://docker.nju.edu.cn",
    "https://docker.mirrors.sjtug.sjtu.edu.cn",
    "https://docker.mirrors.ustc.edu.cn",
    "https://mirror.iscas.ac.cn",
    "https://docker.rainbond.cc",
    "https://do.nark.eu.org",
    "https://dc.j8.work",
    "https://gst6rzl9.mirror.aliyuncs.com",
    "https://registry.docker-cn.com",
    "http://hub-mirror.c.163.com",
    "http://mirrors.ustc.edu.cn/",
    "https://mirrors.tuna.tsinghua.edu.cn/",
    "http://mirrors.sohu.com/"
  ]
}
EOF
⚠️ 注意:修改后需重载配置并重启 Docker:
sudo systemctl daemon-reload
sudo systemctl restart docker

7. 将当前用户加入 docker 用户组(避免每次使用 sudo

# 创建 docker 组(若不存在)
sudo groupadd docker

# 将当前用户加入 docker 组
sudo usermod -aG docker $USER

# 刷新组权限(关键!否则需重新登录)
newgrp docker

二、部署 Dify API 服务

1. 准备中间件服务(如 Redis、PostgreSQL 等)

  • 修改 docker-compose.middleware.yamlmiddleware.env 中的数据卷路径
  • 上传整个 docker/ 目录到服务器
启动中间件
cd /data/dify/docker
docker compose -f docker-compose.middleware.yaml up -d
停止命令:docker compose -f docker-compose.middleware.yaml down

2. 安装构建依赖环境

原因:Dify 使用的 wandb >= 0.16.0 要求本地存在 Go 编译环境;同时 numpy==2.4.1 需要 GCC ≥ 9.3,而 CentOS 7 默认 GCC 仅为 4.8.5。
(1) 安装 Go(1.23.0)
# 下载(使用国内镜像)
wget -O go1.23.0.linux-amd64.tar.gz https://golang.google.cn/dl/go1.23.0.linux-amd64.tar.gz

# 解压到 /usr/local
sudo tar -C /usr/local -xzf go1.23.0.linux-amd64.tar.gz

# 配置 PATH
echo 'export PATH=$PATH:/usr/local/go/bin' >> ~/.bashrc
source ~/.bashrc

# 验证
go version
(2) 安装 Rust(使用 rsproxy.cn 镜像)
# 下载安装脚本
wget -O rustup-init.sh https://rsproxy.cn/rustup-init.sh
chmod +x rustup-init.sh

# 设置国内镜像源
export RUSTUP_DIST_SERVER=https://rsproxy.cn
export RUSTUP_UPDATE_ROOT=https://rsproxy.cn/rustup

# 静默安装(不修改 PATH)
./rustup-init.sh -y --no-modify-path

# 临时加载环境变量
source "$HOME/.cargo/env"

# 验证
rustc --version
cargo --version
(3) 升级 GCC 至 9.3+
# 启用 SCL 源
sudo yum install -y centos-release-scl

# 安装 devtoolset-9
sudo yum install -y devtoolset-9-gcc devtoolset-9-gcc-c++

# 启用新 GCC(仅当前 shell 有效)
scl enable devtoolset-9 bash

# 验证
gcc --version  # 应显示 9.3.x
建议:将 scl enable devtoolset-9 bash 加入 ~/.bashrc 以持久生效(但注意可能影响其他程序)。
(4) 安装 uv(现代 Python 包管理器)
curl -LsSf https://astral.sh/uv/install.sh | sh
source "$HOME/.local/bin/env"

3. 部署 API 服务

  • 修改 .env 文件中的数据库地址、存储路径、日志目录等配置。
  • 上传 api/ 目录到服务器(首次上传时请注释掉 scp-api.sh 中的启动逻辑)。
首次启动流程
cd /data/dify/api

# 安装依赖
uv sync

# 执行数据库迁移(首次必须运行)
flask db upgrade

# 后台启动 API 服务
nohup gunicorn -w 4 -k gevent --bind 0.0.0.0:5019 app:app > dify-api.log 2>&1 &
启动 Celery Worker
cd /data/dify/api

# 后台启动 Worker
nohup uv run celery -A app.celery worker -P gevent -c 1 --loglevel INFO \
  -Q dataset,generation,mail,ops_trace > dify-worker.log 2>&1 &

🔁 后续重启:只需执行

# 启动API服务
nohup gunicorn -w 4 -k gevent --bind 0.0.0.0:5019 app:app > dify-api.log 2>&1 &
# 启动worker
nohup uv run celery -A app.celery worker -P gevent -c 1 --loglevel INFO \
  -Q dataset,generation,mail,ops_trace > dify-worker.log 2>&1 &

三、部署 Dify Web 前端

说明:CentOS 7 无法原生安装 Node.js 20+,因此采用 Docker 容器化部署

1. 构建 Web 镜像(在开发机上操作)

(1) 本地编译(需 Node.js ≥ 22)
# 安装依赖
pnpm install --frozen-lockfile

# 构建(内存不足时增加堆大小)
NODE_OPTIONS="--max_old_space_size=4096" NEXT_CONCURRENT_BUILD_LIMIT=1 pnpm build

DIR1="web/.next/standalone/.next"

# 创建目录(-p 表示递归创建,且不报错如果已存在)
mkdir -p "$DIR1" 
cp -r web/.next/static web/.next/standalone/.next/static && cp -r web/public web/.next/standalone/public 
构建产物位于 standalone/ 目录。
(2) 编写 Dockerfile
# 使用官方 Node.js 22 Alpine 镜像
FROM node:22-alpine

WORKDIR /app

# 复制构建产物
COPY standalone ./

EXPOSE 3000

CMD ["node", "server.js"]

2. 在服务器部署 Web 服务

cd /data/dify/web

# 1. 清理旧容器与镜像
docker stop my-dify-web && docker rm my-dify-web && docker rmi my-dify-web

# 2. 解压新构建包(覆盖 standalone/)
tar -xzf dify-web-standalone.tar.gz

# 3. 构建新镜像
docker build -t my-dify-web .

# 4. 启动容器
docker run -d \
  --name my-dify-web \
  -p 3000:3000 \
  my-dify-web

3. 配置 Web 环境变量

  • 修改 standalone/.env.local 中的 NEXT_PUBLIC_API_URLNEXT_PUBLIC_WEB_URL,指向实际 API 与 Web 地址。
🔄 更新 Web 服务:重复上述“清理 → 解压 → 构建 → 启动”流程,或封装为脚本自动化。

四、注意事项

  1. 权限问题:确保 /data/dify/ 目录对当前用户可读写。
  2. 防火墙:开放 5019(API)、3000(Web)、以及中间件所需端口(如 6379、5432 等)。
  3. 日志监控:定期检查 dify-api.logdify-worker.log
  4. 环境持久化:若使用 scl enable,建议在 ~/.bashrc 中添加 alias 或 wrapper 脚本。

✅ 至此,Dify 已在 CentOS 7 上完整部署。
如遇问题,请优先检查依赖版本、网络连通性及配置文件路径。


希望这份部署文档能帮助你和团队更高效地完成部署!

本文由mdnice多平台发布

平时使用谷歌搜索,搜索 12315 网站出来的第一条竟然是假的,我没注意看域名直接点进去了。
假冒网站的网址: http://36.110.229.139/
真正的网址: https://www.12315.cn/

而且还尝试注册了,收到验证码还发给它了,验证码也是模仿层 12315 的,不知道有什么后果。

下面直接进入核心,不兜圈子。


美国高防云服务器能防御哪些攻击?(蓝易云 CDN 场景解析)

在当前的网络安全对抗环境中,美国高防云服务器的价值不在“能不能扛”,而在于<span style="color:red">能否在攻击持续、手法演进的情况下保持业务可用</span>。从工程实践角度看,它主要覆盖以下几大类攻击面。


一、DDoS 洪水型攻击(核心防御能力) 🌊

这是高防服务器存在的首要理由。

可防御类型

  • UDP Flood
  • ICMP Flood
  • TCP SYN Flood
  • ACK / RST Flood
  • 混合型反射放大攻击

防御原理(简化逻辑)

异常流量 → 清洗中心 → 特征识别 → 丢弃攻击包 → 回源正常流量
  • 大带宽承载用于吸收流量峰值
  • 清洗节点通过包速率、协议异常、源分布判断攻击
  • 正常请求被保留并回源

📌 关键点在于:
<span style="color:red">防的是“量级 + 持续性”,而不是单点规则</span>


二、CC 攻击(应用层消耗型攻击) 🧠

CC 攻击不靠带宽,靠“像人一样访问”。

常见形式

  • 高频 HTTP GET/POST
  • 慢连接(Slow Request)
  • 模拟正常浏览路径的并发请求

美国高防云服务器的应对方式

防御手段说明
访问频率限制单 IP / 单会话 QPS 控制
行为分析识别非人类访问节奏
会话校验Cookie / Token 校验
挑战机制动态验证请求有效性

📌 本质是:
<span style="color:red">让攻击成本无限接近真实用户成本</span>


三、协议层畸形攻击(低层但致命) ⚙️

这类攻击流量不大,但直接打协议实现漏洞。

可防御类型

  • TCP 半连接耗尽
  • 畸形 TCP Flag 组合
  • 非法 MSS / Window Size
  • 重放包攻击

防御机制说明

  • 协议栈参数硬化
  • 状态表容量保护
  • 异常包即时丢弃

📌 这类防御极度依赖底层网络与内核调优,普通云服务器基本无解。


四、反射与放大攻击 🔁

典型特征:
小请求 → 大响应 → 目标被淹没

常见攻击源

  • NTP
  • DNS
  • SSDP
  • Memcached

高防服务器的处理逻辑

识别反射特征 → 阻断响应回程 → 清洗异常源

📌 防御重点不是“挡住请求”,而是:
<span style="color:red">阻断被利用的回包路径</span>


五、扫描、探测与撞库类攻击 🔍

虽然不是传统意义的大流量攻击,但对业务风险极高。

可防御行为

  • 端口扫描
  • 服务指纹探测
  • 登录接口撞库
  • 异常路径探测

防御手段

行为防护方式
高频扫描自动封禁源
异常路径规则阻断
登录异常访问节流

📌 目标只有一个:
<span style="color:red">不让攻击者摸清你的系统结构</span>


六、与 CDN + 高防联动时的攻击覆盖面 🚀

当美国高防云服务器与 CDN 架构配合时,防御能力会发生质变。

联动后的效果

  • 攻击被提前在边缘节点拦截
  • 源站 IP 完全隐藏
  • CC 攻击被拆散到多个节点
攻击者 → CDN 节点 → 清洗 → 高防服务器 → 业务

📌 实战价值在于:
<span style="color:red">攻击永远打不到真正的源头</span>


七、能力边界说明(务实,不吹)⚠️

必须说清楚,美国高防云服务器不解决所有安全问题

不属于防御范围原因
业务逻辑漏洞属于代码层问题
内部权限滥用非网络攻击
程序自身 Bug需开发修复

📌 高防解决的是:
<span style="color:red">可用性与抗压能力</span>,而不是代码安全本身。


八、总结(一句话定性)🎯

**美国高防云服务器的核心价值在于:
在面对 <span style="color:red">大规模、持续、多形态网络攻击</span> 时,
依然能让业务保持“能访问、不中断、不崩溃”。**

对蓝易云 CDN 这类业务来说,它不是“可选项”,而是抗风险的基础设施

从工程视角看,这不是“买防御”,而是为业务争取生存时间