公司动态
Scrapling:绕过反爬的下一代爬虫框架,比 BeautifulSoup 快 774 倍
二零二四年十月, 有一个名为 的库默默地上线了。仅仅过了几个月, 它就疯狂收获了三万八千多颗星, 进而成为了爬虫领域呈现出显著迹象与特性的开源项目。并非是由于营销方面的因素, 而是因为它实实在在地解决了一个让人困扰的问题: 在你费尽心力写好了爬虫之后, 一旦网站进行了改版, 那么选择器就全都失效了。的答案是让爬虫自己学会适应变化。为什么爬虫总是脆弱从事做爬虫工作的人, 都存在着一个共通的噩梦, 那就是在半夜时分, 被报警声给叫醒, 原因是——“爬虫挂掉了”。前往窥看日志, 发觉缘由惊人的一致, 那便是网站进行了改版。或许仅仅只是将.-title改换为了.-item-name , 亦或者把。给嵌套层级额外增添了一层, 那最终的结果究竟是什么状况呢你整个的选择器系统会完全失去有效性, 并且所有的规则都得去颠覆性地重新梳理才行。这并非单个的情形 , 依照2024年的相关数据 , 主流的电商网站 平均进行改版12至15次 , 对于那需求长期监管竞品 、价格以及评论的团队来讲 , 这是那种连续消耗开发资源的不见底的坑。传统的解法有两种带来了一种别样的思路, 那便是自适应的选择器, 它能够从历史里的选择器进行“进化”, 进而自动找寻到处于新位置的目标元素。02, 核心特性深度解析2.1, 多种, 从 HTTP 到无头浏览器, 有一套 API。提供了四个层级的 越底层越快越上层越真实适用场景速度反爬能力静态页面数据简单基本 TLS 伪装需要并发的高吞吐量场景基本 TLS 伪装/ 等反爬开箱即用动态渲染页面完整浏览器模拟核心代码几乎一模一样from scrapling.fetchers import StealthyFetcher, DynamicFetcher # 方式一StealthyFetcher — 绕过反爬 page StealthyFetcher.fetch(https://example.com, headlessTrue, network_idleTrue) products page.css(.product, auto_saveTrue) # 方式二DynamicFetcher — 处理 JS 渲染 page DynamicFetcher.fetch(https://example.com) data page.css(.quote .text::text).getall()它指认的关键在于, 那个等于真值的参数, 一旦开启, 便会针对涉及的元素开展结构特征的记录行动, 这之后, 要是下次再进行取值运算等操作致使选择符号在运用时出现无效状况只要你再次传入相应的等于真值得元素符号, 它就会依据过往留存的特征来自动寻觅与之存在相似之处和关联的元素。2.2 绕过——真的开箱即用这是当前最难被绕开的验证码系统当中的一个, 不少商业方案都得收费, 并且还需要进行维护, 它被内置了绕过的能力, 无需额外去配置。from scrapling.fetchers import StealthyFetcher, StealthySession # 会话模式保持登录状态 with StealthySession(headlessTrue, solve_cloudflareTrue) as session: page session.fetch(https://nopecha.com/demo/cloudflare) data page.css(#padded_content a).getall()注意, 这并非是毫无瑕疵的。针对像企业级这类处于高端范畴的方案而言, 进行维护的相关人员也秉持着十分坦诚的态度去推荐Hyper, 这是一种专注于企业级反爬API的商业性质的服务, 显然这同样是一种脚踏实地的务实态度。2.3 框架——从单次请求到大规模并发爬虫如果你用过 的 会让你感到非常亲切from scrapling.spiders import Spider, Response class MySpider(Spider): name demo start_urls [https://example.com/] async def parse(self, response: Response): for item in response.css(.product): yield {title: item.css(h2::text).get()} # 自动翻页 next_page response.css(.next::attr(href)).get() if next_page: yield self.request(next_page) MySpider().start()但它的能力远不止像 一样爬。关键特性包括2.4 代理轮换——内置from scrapling.spiders import Spider from scrapling.fetchers import ProxyRotator class MySpider(Spider): proxy_rotator ProxyRotator( proxies[http://proxy1:port, http://proxy2:port], rotationcyclic # 或自定义策略 ) # 也可以每个请求单独指定代理 def parse(self, response): yield self.request(response.url, proxyhttp://custom-proxy:port)为其内置了支持循环轮换以及自定义策略的功能。针对那些存在需要多 IP 的大规模爬取情况的场景而言, 这属于一种在开启时便能直接使用的能力, 并不需要再由用户自身去重新创造类似的方法。2.5 AI/MCP 集成——给 AI 用的爬虫 API还发布了MCP, 使得AI Agent诸如、等等能够直接去调用爬虫能力。# 官方提供了一个 MCP serverAI 可以直接发送自然语言指令 # AI: 帮我抓这个页面所有商品的价格 # MCP server 底层调用 Scrapling 返回结构化数据这个方向具备着相当大的想象空间, 传统爬虫是需要人类工程师去撰写选择器的, 然而在与相结合以后, 能够借助自然语言来对数据提取实施控制, 如此一来便能够在极大程度上降低爬虫的使用门槛。03 性能实测真的比 快 774 倍官方给的数据非常激进。让我来解读一下这个数字是怎么来的。的解析速度确实惊人。原因有几个解析引擎是以 Rust 所编写的, 其底层运用了库由 Rust 实现, 并非单纯的, 序列化速度快达 10 倍, 它内置了优化的序列化路径, 能够按需加载, lazy 模式可减少不需要的 DOM 操作。然而必须在客观层面来讲, 774倍的基准测试, 乃是于运用纯CSS选择器进行查询的场景状况之下测出来的。在实际开展使用的过程当中, 你的代码里面必定会存在网络请求、错误处理以及写入数据库等IO操作, 而这相应部分所产生的耗时是无法得以优化的。所以, 真实场景之中的提速情况, 大概处于5至50倍的范围此范围取决于你的爬虫具体是属于CPU-bound类型还是IO-bound类型, 然而, 即便处于这样的情况, 这样的成绩也是极为可观的了。04 谁应该用 适合的场景不太适合的场景05进行横向对比06有一份避坑清单, 其结果为True, 这会增加内存占用, 原因是每次保存元素特征都会消耗内存, 对于超大规模爬取而言需要加以注意, 其结果为True, 默认关闭图片加载, 要是有截图表述需求或者存在其他UI依赖, 就要确认资源加载策略, 更新后可能会暂时失效, 相关规则会不定期更新, 开源项目跟进可能存在时差时其结果为True, 会修改TLS指纹, 某些正常网站可能因此拒绝请求, 需要进行测试, 在某方面可能有兼容问题, 官方推荐Linux/macOS环境, 其结果为True, 不会主动限制速度, 只是过滤掉.txt禁止的URL, 实际请求节奏需要自己调控, 不要滥用共享, 同一个所在里的某物和另一个某物在多线程场景下可能出现问题, 07有一条7天上手路线, 08有一个结尾。爬虫领域一个极为根本的问题被解决了, 那就是脆弱性, 经由自适应选择器以及直接可用的反爬绕过, 使得“写一次, 长期运行”变成了可行的状态。关注度关于38k星, 证实了社区对这个方向予以认可。要是你正在维护爬虫, 且此爬虫需长期运行, 又或者你被反爬弄得焦头烂额, 那么值得你花费一个周末去上手试一试。