这篇文章的题目有点大,但这并不是说我自觉对Python爬虫这块有多大见解,我只不过是想将自己的一些经验付诸于笔,对于如何写一个爬虫框架,我想一步一步地结合具体代码来讲述如何从零开始编写一个自己的爬虫框架 2018年到如今,我花精力比较多的一个开源项目算是Ruia了,这是一个基于Python3.6+的异步爬虫框架,当时也获得一些推荐,比如Github Trending Python语言榜单第二,目前Ruia还在开发中,Star数目不过700+,如果各位有兴趣,欢迎一起开发,来波star我也不会拒绝哈~ 什么是爬虫框架 说这个之前,得先说说什么是框架: 是实现业界标准的组件规范:比如众所周知的MVC开发规范 提供规范所要求之基础功能的软件产品:比如Django框架就是MVC的开发框架,但它还提供了其他基础功能帮助我们快速开发,比如中间件、认证系统等 框架的关注点在于规范二字,好,我们要写的Python爬虫框架规范是什么? 很简单,爬虫框架就是对爬虫流程规范的实现,不清楚的朋友可以看上一篇文章谈谈对Python爬虫的理解,下面总结一下爬虫流程: 请求&响应 解析 持久化 这三个流程有没有可能以一种优雅的形式串联起来,Ruia目前是这样实现的,请看代码示例: 可以看到,Item & Field类结合一起实现了字段的解析提取,Spider类结合Request * Response类实现了对爬虫程序整体的控制,从而可以如同流水线一般编写爬虫,最后返回的item可以根据使用者自身的需求进行持久化,这几行代码,我们就实现了获取目标网页请求、字段解析提取、持久化这三个流程 实现了基本流程规范之后,我们继而就可以考虑一些基础功能,让使用者编写爬虫可以更加轻松,比如:中间件(Ruia里面的Middleware)、提供一些hook让用户编写爬虫更方便(比如ruia-motor) 这些想明白之后,接下来就可以愉快地编写自己心目中的爬虫框架了 如何踏出第一步 首先,我对Ruia爬虫框架的定位很清楚,基于asyncio & aiohttp的一个轻量的、异步爬虫框架,怎么实现呢,我觉得以下几点需要遵守: 轻量级,专注于抓取、解析和良好的API接口 插件化,各个模块耦合程度尽量低,目的是容易编写自定义插件 速度,异步无阻塞框架,需要对速度有一定追求 什么是爬虫框架如今我们已经很清楚了,现在急需要做的就是将流程规范利用Python语言实现出来,怎么实现,分为哪几个模块,可以看如下图示: 同时让我们结合上面一节的Ruia代码来从业务逻辑角度看看这几个模块到底是什么意思: Request:请求 Response:响应 Item & Field:解析提取 Spider:爬虫程序的控制中心,将请求、响应、解析、存储结合起来 这四个部分我们可以简单地使用五个类来实现,在开始讲解之前,请先克隆Ruia框架到本地: # 请确保本地Python环境是3.6+ git clone https://github.com/howie6879/ruia.git # 安装pipenv pip install pipenv # 安装依赖包 pipenv install --dev 然后用PyCharm打开Ruia项目: 选择刚刚pipenv配置好的python解释器: 此时可以完整地看到项目代码: 好,环境以及源码准备完毕,接下来将结合代码讲述一个爬虫框架的编写流程 Request & Response

爬虫也可以称为Python爬虫 不知从何时起,Python这门语言和爬虫就像一对恋人,二者如胶似漆 ,形影不离,你中有我、我中有你,一提起爬虫,就会想到Python,一说起Python,就会想到人工智能……和爬虫 所以,一般说爬虫的时候,大部分程序员潜意识里都会联想为Python爬虫,为什么会这样,我觉得有两个原因: Python生态极其丰富,诸如Request、Beautiful Soup、Scrapy、PySpider等第三方库实在强大 Python语法简洁易上手,分分钟就能写出一个爬虫(有人吐槽Python慢,但是爬虫的瓶颈和语言关系不大) 任何一个学习Python的程序员,应该都或多或少地见过甚至研究过爬虫,我当时写Python的目的就非常纯粹——为了写爬虫。所以本文的目的很简单,就是说说我个人对Python爬虫的理解与实践,作为一名程序员,我觉得了解一下爬虫的相关知识对你只有好处,所以读完这篇文章后,如果能对你有帮助,那便再好不过 什么是爬虫 爬虫是一个程序,这个程序的目的就是为了抓取万维网信息资源,比如你日常使用的谷歌等搜索引擎,搜索结果就全都依赖爬虫来定时获取 看上述搜索结果,除了wiki相关介绍外,爬虫有关的搜索结果全都带上了Python,前人说Python爬虫,现在看来果然诚不欺我~ 爬虫的目标对象也很丰富,不论是文字、图片、视频,任何结构化非结构化的数据爬虫都可以爬取,爬虫经过发展,也衍生出了各种爬虫类型: 通用网络爬虫:爬取对象从一些种子 URL 扩充到整个 Web,搜索引擎干的就是这些事 垂直网络爬虫:针对特定领域主题进行爬取,比如专门爬取小说目录以及章节的垂直爬虫 增量网络爬虫:对已经抓取的网页进行实时更新 深层网络爬虫:爬取一些需要用户提交关键词才能获得的 Web 页面 不想说这些大方向的概念,让我们以一个获取网页内容为例,从爬虫技术本身出发,来说说网页爬虫,步骤如下: 模拟请求网页资源 从HTML提取目标元素 数据持久化 什么是爬虫,这就是爬虫: """让我们根据上面说的步骤来完成一个简单的爬虫程序""" import requests from bs4 import BeautifulSoup target_url = 'http://www.baidu.com/s?wd=爬虫' # 第一步 发起一个GET请求 res = requests.get(target_url) # 第二步 提取HTML并解析想获取的数据 比如获取 title soup = BeautifulSoup(res.text, "lxml") # 输出 soup.title.text title = soup.title.text # 第三步 持久化 比如保存到本地 with open('title.

要想入门以及往下理解深度学习,其中一些概念可能是无法避免地需要你理解一番,比如: 什么是感知器 什么是神经网络 张量以及运算 微分 梯度下降 带着问题出发 在开始之前希望你有一点机器学习方面的知识,解决问题的前提是提出问题,我们提出这样一个问题,对MNIST数据集进行分析,然后在解决问题的过程中一步一步地来捋清楚其中涉及到的概念 MNIST数据集是一份手写字训练集,出自MNIST,相信你对它不会陌生,它是机器学习领域的一个经典数据集,感觉任意一个教程都拿它来说事,不过这也侧面证明了这个数据集的经典,这里简单介绍一下: 拥有60,000个示例的训练集,以及10,000个示例的测试集 图片都由一个28 ×28 的矩阵表示,每张图片都由一个784 维的向量表示 图片分为10类, 分别对应从0~9,共10个阿拉伯数字 压缩包内容如下: train-images-idx3-ubyte.gz: training set images (9912422 bytes) train-labels-idx1-ubyte.gz: training set labels (28881 bytes) t10k-images-idx3-ubyte.gz: test set images (1648877 bytes) t10k-labels-idx1-ubyte.gz: test set labels (4542 bytes) 上图: 图片生成代码如下: %matplotlib inline import matplotlib import matplotlib.pyplot as plt import numpy as np from keras.datasets import mnist (train_images, train_labels), (test_images, test_labels) = mnist.

这篇论文提供了一个关于字符级卷积网络(ConvNets)在文本分类中应用实证研究,我们构建了几个大型数据集,以表明字符级卷积网络可以实现最先进的或竞争性的结果,针对传统模型(如词袋,n-gram及其TFIDF变体)和深度学习模型(如基于单词的ConvNets和循环神经网络)进行比较 Introduction 文本分类是自然语言处理中的一个经典问题,需要给自由文本文档分配预定义的类别。文本分类的研究范围包括从设计最佳特征到选择最佳机器学习分类器。到目前为止,几乎所有的文本分类技术都是基于单词的,一些单词有序组合的简单统计,如 N-gram,通常表现最好 另一方面,许多研究人员发现卷积网络(ConvNets)从计算机视觉应用到语音识别等,对于从原始信号中提取信息都有不错的效果,特别是,在深度学习研究的早期使用的延时网络本质上是对序列数据进行建模的卷积网络 在这篇文章中,我们探讨在字符层面上把文本作为一种原始信号,并将其应用于一维随机网络中。对于本文我们只使用文本分类任务作为例证来说明ConvNets理解文本的能力,从历史上看,我们知道ConvNets通常需要大规模数据集才能工作,因此我们也构建了其中的几个,提供了一系列与传统模型和其他深度学习模型的比较 将卷积网络应用于文本分类或自然语言处理是文献研究的热点,研究表明,ConvNets可以直接应用于分布式或离散的嵌入词,而不需要任何语言的句法或语义结构的知识,事实证明,这些方法与传统模型相比具有竞争力 还有一些相关的工作使用字符级特性进行语言处理,这些包括使用带有线性分类器的字符级n-gram,并将字符级特性合并到ConvNets,特别是,这些ConvNet方法以单词为基础,在单词或单词n-gram层提取字符级特征,形成分布式表示。对词性标注和信息检索的改进进行了观察 本文是第一篇只将字符应用于ConvNets的文章,我们证明,在大规模数据集上训练时,深度ConvNets不需要词汇知识,此外以前的研究结论认为,ConvNets不需要语言的句法或语义结构知识,这种工程上的简化对于能够适用于不同语言的单一系统来说是至关重要的,因为字符总是构成一个必要的结构,无论能否做到分割成词,仅处理字符还有一个好处,那就是可以自然而然地学会拼写错误和表情符号等不正常的字符组合 Character-level Convolutional Networks 在这部分,我们介绍了用于文本分类的字符级ConvNets的设计,设计是模块化的,其中通过反向传播获得梯度以执行优化 Key Modules 主要组件是简单卷积模块,它简单地计算一维卷积。假设我们有一个离散输入函数: 和一个离散核函数: 具有步幅d的f(x)和g(y)之间的卷积: 被定义为: 其中c = k - d + 1是偏移常数,这个非常合用的模块使我们能够对 convnet 进行比6层更深的训练,而其他所有层都失败了。 A theoretical analysis of feature pooling in visual recognition.的分析可能对这个问题有所帮助 该模型使用的非线性函数是h(x) = max{0, x},这使得我们的卷积层类似于校正的线性单位(ReLUs),使用的算法是128个小批量的随机梯度下降(SGD),使用动量0.9和初始步长0.01,每3个时间段减半,持续10次。 每个时期采用固定数量的随机训练样本,这些样本在类之间均匀采样。稍后将详细说明每个数据集的此数字。 实现使用 Torch 7完成 Character quantization 我们的模型接受一系列编码字符作为输入,通过为输入语言规定大小为m的字母表来完成编码,然后使用1-m编码(或“one-hot”编码)量化每个字符。然后,将字符序列变换为具有固定长度l0的这种m大小的向量的序列。忽略超过长度l0的任何字符,并且包括空白字符的不在字母表中的任何字符被量化为全零向量。字符量化顺序是向后的,因此字符的最新读数总是放在输出开始的附近,使得完全连接的图层可以很容易地将权重与最新读数联系起来 我们所有模型中使用的字母由70个字符组成,包括26个英文字母,10个数字,33个其他字符加一个全零向量: abcdefghijklmnopqrstuvwxyz0123456789-,;.!?:'\"/\\|_@#$%^&*~`+-=<>()[]{} 稍后我们将会生成一个字母表加上大小写的模型并进行比较 模型设计 论文中设计了large和small两种卷积网络,都由6个卷积层和3个全连接层共9层神经网络组成 由于字母表长度为70,因此我们的输入特征为70,输入特征长度论文设定为1014,看起来1014个字符已经可以捕获大部分感兴趣的文本,我们还在三个全连接层之间插入两个dropout层以实现模型正则化,dropout概率为0.5,表1列出了卷积层的配置,表2列出了全连接层的配置: 表1:实验中的卷积层,卷积层的步幅为1,并且池化层都是非重叠的,因此我们省略了他们的步幅描述 使用Gaussian distribution初始化权重,初始化模型的均值和标准差分别为: large model:(0, 0.02) small model:(0, 0.05) 表2:实验中的全连接层,最后一层的输出单元数由问题决定,例如,对于10分类问题将是10

原文地址:How to Write Beautiful Python Code With PEP 8 作者:Jasmine Finer 翻译:howie6879 PEP 8有时候读作PEP8或者PEP-8,是一份提供如何编写Python代码指南和最佳实践的文档,由Guido van Rossum, Barry Warsaw, Nick Coghlan在2001年完成。PEP 8主要注重于提高 Python 代码的可读性和一致性。 PEP全称为:Python Enhancement Proposal,一个PEP是一份文档,它描述了为Python提出的新特性以及为社区编写的Python方面的文档,比如设计和风格。 本教程概述了PEP 8中列出的关键指南,它的目标读者是初级到中级程序员,因此我没有涉及一些最高级的主题。不过你可以通过阅读完整的PEP 8 — Style Guide for Python Code | Python.org文档来学习高级主题。 在本教程结束时,你将能够: 编写遵从PEP 8规范的代码 理解PEP 8中列出的指导原则背后的原因 设置你的开发环境,以便开始编写符合PEP 8标准的Python代码 Why We Need PEP 8 可读性很重要 PEP 8规范存在的目的在于提高Python代码的可读性,但为什么可读性如此重要?为什么编写具有可读性的代码是Python语言的指导原则之一? 正如Guido van Rossum所说:”代码阅读的频率远远高于编写的频率“。你可能花费几分钟或一整天时间编写一段代码来处理用户身份验证,一旦你写完它,你就再也不会重写一次,但是你肯定会再读一次,这段代码可能仍然是你正在进行的项目的一部分。每次你回到那个代码文件,你必须要记住那部分代码是做什么的以及你为什么要写它,所以可读性很重要。 如果你是Python新手,在你编写代码之后的几天或几周内还要你记住代码片段的含义可能有点困难。如果你遵循PEP 8标准,你可以很确定你对你的变量命名得很好,你会知道你添加了足够的空格,因此更容易遵循代码中的逻辑步骤,你还可以对你的代码进行很好的注释,所有的这些都意味着你的代码具有更高的可读性,也更容易再次阅读。作为初学者,遵循PEP 8的规则可以使学习Python成为更愉快的任务。 如果你正在找工作,那么遵循PEP 8标准尤为重要,编写清晰可读性高的代码更会突出你的专业性,这将会侧面告诉你的老板,你了解怎么很好地构建你的代码。 如果你拥有很多编写Python代码的经验,然后你可能需要和其他人协作开发,编写可读性高的代码在这里至关重要,其他人可能此前从未看过你这样风格的代码,他必须重新阅读且理解你的代码风格,如果拥有你遵循和认可的指南将使其他人更容易阅读你的代码。 Naming Conventions 明了胜于晦涩

如何用Python创建一个简单的神经网络 原文地址:How to Create a Simple Neural Network in Python 作者:Dr. Michael J. Garbade 翻译:howie6879 理解神经网络如何工作的最好方式是自己动手创建一个,这篇文章将会给你演示怎么做到这一点 神经网络(NN),也称之为人工神经网络(ANN),它是机器学习领域中学习算法集合中的子集,其核心概念略似生物神经网络的概念。 拥有五年以上经验的德国机器学习专家Andrey Bulezyuk说过:神经网络正在使机器学习发生革命性的巨变,因为他们能够跨越广泛的学科和行业来高效地建模复杂的抽象。 基本上,一个ANN由以下组件构成: 输入层:接受传递数据 隐藏层 输出层 各层之间的权重 每个隐藏层都会有一个精心设计的激活函数,对于此教程,我们将会使用Sigmoid激活函数 神经网络的类型有很多,在这个项目中,我们准备创建一个前馈神经网络,此类型的ANN将会直接从前到后传递数据 训练前馈神经元往往需要反向传播,反向传播为神经网络提供了相应的输入和输出集合,输入数据在被传递到神经元的时候被处理,然后产生一个输出 下面展示了一个简单的神经网络结构图: 而且,理解神经网络如何工作做好的办法就是去学习从头开始构建一个神经网络(不使用任何第三方库,作者意思应该是不使用任何机器学习库)。 在本文中,我们将演示如何使用Python编程语言创建一个简单的神经网络。 问题 这里用表格列出了我们需要解决的问题: 我们将会训练一个特定的神经网络模型,当提供一组新数据的时候,使其能够准确地预测输出值。 如你在表中所见,输出值总是等于输入数据的第一个值,因此我们期望的表中输出(?)值是1。 让我们思考看看能不能使用一些Python代码来给出相同的结果(再继续阅读之前,你可以在文章末尾仔细地阅读此项目的代码) 创建一个神经网络类 我们将在Python中创建一个NeuralNetwork类来训练神经元以提供准确的预测,该类还具有一些其他的辅助函数 尽管我们没有使用任何一个神经网络库用于这个简单的神经网络示例,我们也会导入numpy包来协助计算。 该库带有以下四个重要方法: exp:用于生成自然指数 array:用于生成矩阵 dot:用于乘法矩阵 random:用于生成随机数(注意:我们将对随机数进行播种以确保其有效分布) 应用 Sigmoid 激活函数 该神经网络将使用Sigmoid function作为激活函数,其绘制了一个典型的S形曲线: 此函数可以将任意值映射到区间0~1之间,它将帮助我们规范化输入值的和权重乘积之和。 随后,我们将创建Sigmoid函数的导数来帮助计算机对权重进行必要的调整。 一个Sigmoid函数的输出可以用来生成它的导数,例如,如果输出变量是X,那么它的导数将是x * (1-x)。 推导过程如下: 训练模型 在这个阶段我们将教导神经网络进行准确预测,每个输入都有一个权重 - 正面或负面。 这意味着,如果输入包含一个大的正面或者负面的权重数值将会更多地影响输出值 请记住,在最开始阶段我们会对每个权重分配一个随机值 下面是我们在这个神经网络示例问题中使用的训练过程: