plainify

【译】如何创建一个可复用的网页爬虫

原文地址:How to Create a Reusable Web Scraper 网页爬虫是个非常有趣的玩具。不过不好玩的是,我们需要根据不同网页上的元素不断的调整自己的代码。这就是为什么我要着手实现一个更好的网页爬虫项目——通过该项目可以以最少的更改实现对新网页的爬取。 第一步是将网页爬虫按照逻辑分成每个独立的部分: 页面请求器 页面验证器 模板页面处理器 页面请求器 页面请求器的实现有一些技巧。下载网页时要考虑很多因素。你需要确保你可以随机的使用用户代理,并且不要过于频繁地从同一域中请求。 此外,停下手头的工作去分析为什么网页无法下载是一件出力不讨好的事。尤其是当你的爬虫已经在多个站点运行了好几个小时的情况下。因此,我们会处理一些请求,并将它们保存为文件。 将请求保存到文件中还有另外一个好处。你不必担心一个标签的消失会影响到你的爬虫。如果页面处理器是独立的,并且你已经完成了页面的下载,你还可以根据需要快速且频繁的对其进行处理。如果发现有另一个要抓取的数据元素怎么办?别担心。只需添加一个标签,然后在你已下载的页面上重新运行处理器即可。 以下是一些实际情况下的示例代码: import requests import pickle from random import randint from urllib.parse import urlparse def _random_ua(): ua_list = ["user agent1, user agent2", "user agent3"] random_num = randint(0, len(ua_list)) return ua_list[random_num] def _headers(): return { 'user-agent': _random_ua() } def _save_page(response): uri = urlparse(response.url) filename = uri.netloc + ".pickle" with open(filename, 'wb+') as pickle_file: pickle....

plainify

【译】13 个你应该选择/考虑使用 Flutter 的理由

原文地址:13 Reasons Why you should choose/ consider to move to Flutter 13 个你应该转向 Dart 并且选择或者学习利用 Flutter 去开发你的下一个 app 的理由。 如今的企业需要在选择移动技术时做出关键选择。他们不断的测试和评估技术,以求不论用户使用什么移动设备或操作系统都能有强大的数字体验。企业如果不能提供易于使用的产品和服务,那么无论使用何种渠道或设备,都有可能落后于竞争对手。 目前面临的挑战便是跨平台应用的开发存在问题。在某些情况下,尽管开发人员尽了最大努力,其用户体验仍然落后于原生 app 。近年来,我们看到了各种移动框架的出现,如 React Native、Xamarin 和 AngularJS ,它们帮助我们更容易地产生较好地数字体验。最近我们看到一个新玩家加入了这场游戏——谷歌的 Flutter。 从内部来看,Flutter 看起来像是谷歌各种技术和概念的大杂烩,然而却产生一个不可思议的强大的移动框架。它是基于 Dart (谷歌的内部编程语言)开发的,它可以让 Flutter 访问 Skia 图形库,而这正是 Chrome 浏览器所使用的。除此之外,Flutter 与谷歌的 Material Design 规范紧密结合;其中最著名的便是 Android 用户已经熟知的“卡片图案”。 让我们看看 13 个选择 Flutter 作为你的开发环境甚至可以选择它开始你的职业生涯的理由, 1. Flutter 克服了传统跨平台的限制 长期以来,创建真正的跨平台方法一直是技术顾问的苦恼所在,他们厌倦了为同一产品制作多个版本。但是,实际上,跨平台应用的用户体验通常落后于原生 app,因为你经常需要即时编译 JavaScript 来构建 UI 体验。 使用 Flutter,你不仅可以拥有“一次编写”的优势,还可以创建高性能的“原生”体验,因为 Flutter 应用程序是提前编译出机器可执行的二进制文件。它克服了其他跨平台方法中的一些常见问题。...

plainify

【译】5 分钟内从单体架构迁移到微服务架构

“微服务架构是一种将单体应用程序开发为一套小型服务的方法。”——马丁 · 福勒。 首先,我们需要明白什么是单体架构。因此,我将向你展示如何修改它的域,,以便为微服务架构做好准备。最后,我将会简要地告诉你微服务架构的基础知识,并讨论其优缺点。 单体架构 每一种非垂直拆分的架构都是单体架构。软件设计中的垂直拆分意味着将应用程序划分为更多可部署的单元。这并不意味着单体架构不能水平划分。 单体这个词指的是软件的体系结构是由一个后端单元组成。我之所以说后端,是因为我认为单体架构可以在具有多个 UI(如 Web 和移动设备)的同时,仍然可以被看作为一个整体。 组件之间的通信主要通过方法的调用。 如果你的前端和后端是在物理上隔离的,但是它们仍然是一个整体,例如 API 和 Web 客户端。 除非你将后端划分为更多部署单元,否则在我看来你依旧是在使用单体架构。 单域模型 “域是计算机程序的目标主题领域。 形式上,它代表特定编程项目的目标主题。”—— 维基百科 用我的话说,域就是软件存在的原因和目的。我在 3 Domain-Centric Architectures Every Software Developer should Know 这篇文章中写了有关域的几个观点。 下图是一个将在线商城域可视化的结果。 Sales 和 Catalog 子域包含单个的 Product 实体。这种做法是不可取的,因为这将导致一个地方出现更多的问题。这违反了关注点分离原则。 强迫一个实体承担更多的责任,显然是不合理的。实体在这两种上下文中都包含未使用的属性。Sales 不需要知道产品的类别,并且对于 Catalog 来说,知道 Product 是如何将信息传递给客户并没有任何用处。 为了避免这个问题,我们需要找到 Sales 和 Catalog 上下文的边界来将它们分开。这就引出接下来要说的限界上下文。 限界上下文 限界上下文是上下文的边界,参考 [Idapwiki.com](https://ldapwiki.com/wiki/Bounded Context) 要指定限界上下文,我们需要识别出一个模型仍然有效的上下文范围。 我们可以通过对域中的每个实体问一个简单的问题来验证模型,即:这个实体对于哪个上下文有效? 当一个实体对多个上下文有效时,那么它应该被划分到多个上下文中。每个实体都具有与上下文相对应的属性。这一步结束后,你的应用就准备好迁移到微服务架构了。 下图是从在线商城域中对 Product 分离的实体类的可视化结果。 微服务架构 微服务架构是因为微服务从而闻名。它是不断细分的单体。微服务将大型系统划分为较小的部分。...

plainify

【译】Flutter 挑战之 WhatsApp

Flutter Challenges 是一项尝试利用 Flutter 重新创建特定的应用程序 UI 或设计的挑战。 此次挑战将尝试 Whatsapp Android 应用程序的主界面。 请注意将重点放在 UI 上而不是实际获取消息。 开始 WhatsApp 的主界面包括: 一个带有搜索操作和菜单的 AppBar 在 AppBar 的底部有四个标签 一个用于拍照的相机标签 一个用于多种用途的 FloatingActionButton 一个“聊天”标签可查看所有对话 一个“状态”选项卡可查看所有状态 一个“打电话”选项卡可查看所有的通话记录 ...

plainify

【译】Flutter 系列入门教程五: 网格

介绍 Flutter GridView 几乎与 ListView 相同, 只是它提供了与 ListView 单向视图的 2D 视图比较。 同时它也是移动应用开发中非常受欢迎的小部件。 如果你不相信我, 那就举个例子, 打开你手机中的任何一个电子商务应用, 它肯定是依赖于 ListView 或 GridView 来显示数据的。 Amazon 移动应用程序利用网格显示数据 另一个是 PayTM, 它是印度流行的在线钱包服务应用之一, 它广泛使用网格布局来显示不同的产品 ...

【译】HTTP/2 常见问题解答

**本文翻译自: 《HTTP/2 Frequently Asked Questions》, 如有侵权请联系删除, 仅限于学术交流, 请勿商用。 如有谬误, 请联系指出。 ** HTTP/2 常见问题解答 以下是有关 HTTP/2 的常见问题解答。 一般问题 为什么要修订 HTTP ? 谁制定了 HTTP/2?? HTTP/2 与 SPDY 的关系是什么? 究竟是 HTTP/2.0 还是 HTTP/2? 和 HTTP/1.x 相比 HTTP/2 的关键区别是什么? 为什么 HTTP/2 是二进制的? 为什么 HTTP/2 需要多路传输? 为什么只需要一个 TCP 连接? 服务器推送的好处是什么? 消息头为何需要压缩? 为什么选择 HPACK? HTTP/2 可以让 cookies (或者其他消息头)变得更好吗? 非浏览器用户的 HTTP 是什么样的? HTTP/2 需要加密吗? HTTP/2 是怎么提高安全性的呢? 我现在可以使用 HTTP/2 吗? HTTP/2 将会取代 HTTP/1....

【译】Javascript中的call(), apply() 和 bind()

回顾一下 “this” 我们了解到, 在面向对象的 JS 中, 一切都是对象。 因为一切都是对象, 我们开始明白我们可以为函数设置并访问额外的属性。 通过原型给函数设置属性并且添加其他方法非常棒…**但是我们如何访问它们? ! ? ? ? ! ** 当他说 “myself” 时, 他的确意味着 ‘this’ 我们介绍过 this 关键字。 我们了解到每个函数都会自动获取此属性。 所以这时, 如果我们创建一个有关我们函数执行上下文的抽象模型(我不是唯一一个这么做的人! … 对吗? ! ? ! ), 它看起来就会像这样: ...

【译】JetPack Compose for Desktop 初体验

目前为止,我们只在 Android 开发中看到 Jetpack Compose。今天,我们将进入一个崭新的阶段,因为 JetBrains 宣布了 IntelliJ 的早期访问版本,允许你使用 Jetpack Compose 来构建 Windows 应用程序。 关于如何使用 Jetpack Compose for desktop,我计划在未来写一些文章加以阐述,本文是这个系列的第一篇文章。上个月,JetBrains 发布了 Compose for desktop Milestone 2,为开发者们带来了更好的开发体验和可操作性。 和往常一样,JetBrains 在继续尝试通过提供独家项目引导来简化开发者的开发流程。在 Compose for desktop 的早期版本中,他们为 IntelliJ 增加了一个桌面项目引导,可以让我们在几秒内配置好项目。 在开始开发之前,你需要安装 IntelliJ IDEA 2020.3 或更高版本。 使用项目模版快速开始 正如我前面所说,项目模板是 IntelliJ 最好用的东西之一。安装完 IDE 后,启动应用程序。你会看到如下的界面: 然后点击顶部栏的 “New Project “按钮,这一操作将会跳转至选择应用程序类型的界面。如下所示: 首先,我们需要从左侧菜单中选择 Kotlin,然后修改项目名称和位置。之后,我们需要选择项目模板。这是配置项目的一个重要步骤。我们需要从项目模板列表中挑选桌面模板,向下滚动就能找到。然后你需要选择项目的 JDK,这里我建议使用 JDK 11。 然后点击“Next”按钮,这将会跳转至确认 Compose 模块的界面。现在点击“Finish”按钮,IntelliJ 将通过自动下载适当的 gradle 为你配置整个项目。 运行你的第一个桌面应用 如果进展顺利,整个桌面项目加载完成后你将会看到以下界面: 此时,你可以运行该应用程序了。由于某些原因,Main.kt 在右上角的“运行”按钮旁边没有被默认选中,所以它会要求你配置项目。为了解决这个问题,你需要在 Main.kt 文件内的主函数旁边点击绿色的“运行”按钮。...

【译】Post-training 量化

Post-training 量化是一种可以减小模型大小, 同时降低 3 倍延迟并且仍然能够保持模型精度的一般方法。 Post-training量化将权重从浮点量化为 8 位精度。 此技术在 TensorFlow Lite model converter 中作为一个功能选项被使用。 import tensorflow as tf converter = tf.contrib.lite.TocoConverter.from_saved_model(saved_model_dir) converter.post_training_quantize = True tflite_quantized_model = converter.convert() open("quantized_model.tflite", "wb").write(tflite_quantized_model) 在推理时, 权重值从 8 位精度转换为浮点数, 并使用浮点内核进行计算。 此转换只执行一次并进行缓存以减少延迟。 ...

plainify

【译】Slidable: 一个有关 Flutter 的故事

概要 这是创建 Slidable 小部件背后的故事(点击这里)。 他是一个当您向左侧或右侧滑动时, 可以在列表项上添加上下文操作的小部件。 这一切是如何开始的呢...