Python爬虫:识别网页的验证码(tesseract-OCR)

在实际的爬虫操作中,处于安全等原因网站会设置非常多的反爬虫手段来限制网络爬虫,最常见的比如设置图形验证码,来识别访客是否为机器人

但是由于python拥有许多强大的图像识别库,所以最简单也是最原始的图形验证码目前已经慢慢没落了,我找了很久发现中国知网的注册界面目前居然还在使用中~ ^ ^

获取网页验证码

首先是获取验证码图片的目标链接,我使用xpath找到html标签中验证码的src链接,读取内容后发现并不能得到生成验证码的对应id,以为是知网做了对爬虫头的限制,于是在headers里添加了“Referer”“Accept-Encoding”等信息,但是并没有效果。抓包在Doc中发现网页HTTP请求的方法为”GET“方法,尝试不加id也得到了验证码图片


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
import requests
from lxml import etree

headers = {
"method": "GET",
"Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9",
"Accept-Encoding": "gzip, deflate, br",
"Cache-Control": "max-age=0",
"scheme": "https",
"accept-language": "zh-CN,zh;q=0.9",
"Cookie": "U:M_distinctid=1809edfcf6e8ff-088ab0a6edb385-17333273-1fa400-1809edfcf6f9fe; _pk_ref=["","",1651932918,'https://www.baidu.com/link?url=PnlS4wubLFxXVNXrTBRCZMAhA0P5TZLlCBAhBvXfLke&wd=&eqid=e52482a8001102070000000562767ee2']; Ecp_ClientId=1220507221503170167; Ecp_IpLoginFail=22050736.161.51.128; Ecp_ClientIp=36.161.51.128; language=chs; _pk_id=2ce0e7fb-229f-4440-a78b-57771deac2fe.1651932918.1.1651933578.1651932918.; ASP.NET_SessionId=he1no3kmgo3bwuktv1xa1lhs; SID_mycnki=020101",
"user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/101.0.4951.54 Safari/537.36",
"Referer": "https://www.cnki.net/"
"Sec-Fetch-Dest:" 'document',
"Sec-Fetch-Mode": 'navigate',
"Sec-Fetch-Site": 'same-origin',
"Sec-Fetch-User": '?1',
"Upgrade-Insecure-Requests": '1'
}
url = "https://my.cnki.net/Register/CommonRegister.aspx?returnUrl=https://www.cnki.net#"
r = requests.get(url, headers=headers).content.decode('utf-8')
html = etree.HTML(r)
link=html.xpath('//*[@id="commonRe"]/div[10]/div[3]/a/img/@src')[0]
img_url = "https://my.cnki.net/Register/" + link
img = requests.get(img_url, headers=headers,stream=True)

with open('checkcode.jpg','wb')as file:
file.write(img.raw.read())


Read More

Numpy & Pandas

本文主要记录一些Numpy和Pandas的方法

Numpy

1.惯用写法:

1
import numpy as np

2.从列表生成一个矩阵:

1
2
3
import numpy as np

print(np.array([[0,1,2,3,4,5],[6,7,8,9,10,11]]))

创建矩阵

3.创建全0或全1矩阵:

1
2
3
4
import numpy as np

print(np.zeros((3,4)))
print(np.ones((5,5)))

0/1矩阵

4.通过.shape得到当前矩阵的尺寸,通过.reshape()将当前矩阵转置

1
2
3
4
5
import numpy as np

print(np.zeros((3,4)))
print(np.zeros((3,4)).shape)
print(np.zeros((3,4)).reshape(4,3))

获取矩阵的尺寸,转置

5.使用arange()创建递增/递减的数列

1
2
3
import numpy as np

print(np.arange(1,10))

arange()

6.使用linspace()获取一个等分的区间序列,第三个参数是输出样本的总数

1
2
3
import numpy as np

print(np.linspace(1,100,10))

linspace()

7.通过random.rand()生成随机数组

1
2
3
import numpy as np

print(np.random.rand(3,4))

随机数组

8.Numpy中默认的数据类型为64位浮点数,可以在创建数组时使用dtype参数指定其他的数据类型

1
2
3
import numpy as np

print(np.ones((3,4),dtype=np.float32))

numpy数据类型

9.对先有的数组,也可以使用astype()来更改数据类型

1
2
3
4
5
6
import numpy as np

array0=np.ones((3,4),dtype=np.float32)
array1=array0.astype(int)

print(array0,array1)

数据类型转换

10.Numpy数组可以直接与一个数进行运算,这个过程称之为广播;两个不同尺寸的数组也可以直接进行运算,这期间numpy会自动将两个数组扩展到相同的尺寸

1
2
3
4
5
6
7
8
9
10
import numpy as np

array0=np.array([1,2,3])
array1=np.array([4,5,6])
array2=np.array([[7],
[8],
[9]])

print(array0*10)
print(array1+array2)

numpy的广播与numpy中不同尺寸数组的运算

Read More

Django项目:订单管理系统

1.Django简介

Django是一款开源的python web应用框架,采用MTV(Model-Template-View)模式,其中Model负责对象与数据库的映射(ORM),Template通过接口等方式将前端页面传递给用户,View视图函数对应业务逻辑,在合适的时候调用Model或Template

除去MTV模型以外,Django还有一个URL控制器,分别将不同的URL请求传递给不同的View视图函数处理,再通过各自的View函数来调用对应的Model和Template

2.Django项目:订单管理系统

1.Django项目的创建

在python 3中安装完成Django库后,可以在CMD或Pycharm终端里执行:django-admin startproject itemproj来创建Django项目

也可以在Pycharm专业版本直接创建一个Django项目,这样会自动生成一个空的Template文件夹,以及在settings.py中生成Template对应的路径。还可以直接创建初始APP,这里没有做

(本文使用的Django版本为3.2.4)

Django项目创建
执行创建完成后,系统会为我们生成这样一个初始目录:

Django目录
其中:

· manage.py是Django项目管理的工具脚本,执行Django命令时通过这个文件进行管理操作

· itemproj/settings.py是Django项目的配置文件,包括了App配置、Django中间件、数据库等重要设置,在实际开发中要经常修改其中内容

· itemproj/urls.py是URL路由映射文件,其中声明了前端发送的各种http请求,再通过各级路由文件来寻找到对应的View视图函数来进行处理

· itemproj/wsgi.py,WSGI是Python web服务网关接口规范(Web Server Gateway Interface)的简称,由wsgi web server和wsgi web application两部分组成,是运行在同一个python进程中的两个模块

wsgi web sever接收了http请求以后调用wsgi web application接口,处理请求的具体内容,处理完成后再将结果返回给wsgi web server,通过wsgi web server将请求传递给前端,如图所示(Django官方文档):

WSGI
· itemproj/asgi.py,ASGI即异步网关协议接口(Asynchronous Server Gateway Interface),是一个介于网络协议服务和python应用之间的标准接口,用于处理通用类型的协议。参考自Django官方文档的资料,ASGI是为了支持异步网络服务器和应用而出现的新的python标准,可以将ASGI理解为WSGI协议的扩展

ASGI

2.Django生命周期

了解了Django项目基本组成后,Django的生命周期也基本明朗:前端发起URL请求WSGIDjango中间件URL路由View视图函数Model数据库交互Template模板进行html渲染Django中间件WSGI前端页面

3.Django项目启动

通过在Pycharm终端中执行python manage.py runserver来启动Django服务,系统默认在:8000端口上执行

Django启动
可以在settings.py中增加ALLOWED_HOSTS的参数,来增加支持的hosts,这里新增一个localhost。也可以自定义端口号等

1
ALLOWED_HOSTS = ['localhost']

Read More

基于卷积神经网络的面部年龄识别

1.训练模型和框架

1.1 Adience数据集

Adience图片集包括Flickr等相册,通过从iPhone5(或更高版本)的智能手机等移动设备自动上传并进行组装,由其作者根据知识共享(CC)许可向公众发布。数据集提供了共计26580张面部照片的数据和基准,旨在尽可能真实地应对实际成像并做出判断。数据的标签有年龄组、性别、户外等,可用于监督学习的人脸识别对年龄的研究。Adience收录的数据信息包括主体外观、动作、噪点、光线等实际情况中进行图像采集时包含的动态变化,具有环境适应性强、应用范围广的特点。

1.2 Caffe框架

Caffe(Convolutional Architecture for Fast Feature Embedding)采用CUDA架构,可在CPU和GPU上进行高速运算,是一个兼具了效率、表达和思维模块化的卷积神经网络框架。

Caffe的数据结构以Blobs-Layers-Net的形式存在。

Blobs是Caffe的核心数据格式,提供了统一的内存接口,并且可以在CPU与GPU之间进行数据同步。主要通过四维张量(NumberChannelweight*high)的形式,按照C-contiguous方式(数组的行存储连续且不间断)来存储和交流网络中的权重、激活值、正反向数据。

Layers是Caffe模型的关键内容,是组成神经网络和进行相关计算的基础。所有的Layer层都可以接收底层输入的Blobs,并向高层输出Blobs。Layers每一层都定义三种重要的计算:初始化(Setup)、向前传播(Forward)、向后传播(Backward)。

其包含的运算有:

· 1.load data:数据载入

· 2.Convolve filters:卷积层,进行卷积。

· 3.Pooling:池化层,进行池化。

· 4.Nonlinearities:非线性映射运算,即激活函数。

· 5.Inner Products:内积运算。

· 6.Normalize:归一化

· 7.Compute losses:损失函数计算,如softmax、hinge。

Net是一个由一系列连接的Layer层组成的有向无环图(Directed Acyclic Graph,DAG)。caffe会在向前传播或向后传播时,对DAG中的所有层进行记录,确保其准确性。

2.基于卷积神经网络的人脸识别

2.1 卷积神经网络架构

使用的架构包括3个卷积层、2个全连接层和1个最终输出层。具体定义卷积层如下:

1.Conv1:将内核大小为337的共计96个像素节点的过滤应用于输入第一卷积层中,经过修正线性单元ReLU(激活函数)处理后,池化层采用保留最大值(max-pooling)的规则,选择一个两像素跨度的3*3区域中最大值,进行池化,再经过局部响应归一化层(Local Response Normalization,LRN)。

2.Conv2:上一层的输出(96×28×28)由第二个卷积层进行处理,包括对256个大小为9655的像素过滤。同样的,经过一个修正线性单元ReLU,最大池化层,和一个与之前参数相同的局部响应归一化层。

3.Conv3:第三层卷积层通过对一组384个大小为25633的像素过滤来对256×14×14的 Blob进行处理,接着经过修正线性单元ReLU和一个最大池化层。

再通过下列方式定义完全连接层:

1.第一个完全连接层包含了512个人工神经元,用于接收第三卷积层的输出结果。接着再通过修正线性单元ReLU和Dropout层(防止CNN过拟合)。

2.第二个完全连接层接收第一个完全连接层的512个人工神经元空间大小的输出(同样包含512个人工神经元),再通过修正线性单元ReLU和Dropout层。

3.第三层完全连接层映射最终的分类结果。

最终,最后一个完全连接层的输出会被反馈到为每个类别分配概率的Softmax层,预测其本身通过给定的测试图像的最大概率。

2.2 年龄预测

人的面部特征无时不刻发生着微妙变化反映出其年龄的不断增长,在最理想的情况之下,人的面部特征随着人的成长应该表现出正相关的关系,那么年龄估计就是一个广义上的回归问题。然而实际上仅通过回归的方法来判断一个人的年龄是靠不住的,即便一个正常的自然人也很难推断出观察对象的准确实际年龄。

但是人眼可以对观察对象做出一个大致判断,较为准确的预测出对方的年龄所在区间。这样,就对对方的年龄有了初步估计。这样,就可以对年龄区间进行一个分类,以进一步研究人脸和年龄的关系。

Adience数据集将人的年龄划分为了八个类别,分别为:[0-2]、[4-6]、[8-13]、[15-20]、[25-32]、[38-43]、[48-53]、[60 -]。因此,深度神经网络在最终的Softmax层中有8个节点,分别对各年龄段进行分类。

1
2
MODEL_MEAN_VALUES = (78.4263377603, 87.7689143744, 114.895847746)
ageList = ['(0-2)', '(4-6)', '(8-12)', '(15-20)', '(25-32)', '(38-43)', '(48-53)', '(60-100)']

Blob输入网络进行年龄的检测,并且年龄检测程序向前传播。

1
2
3
ageNet.setInput(blobs)
agepredction = ageNet.forward()
age = ageList[agepredction[0].argmax()]

Read More

卷积神经网络算法

神经网络(Neural Networks,NN)是人工智能研究领域的重要组成部分,是大数据与人工智能技术发展的重要动力。

1.卷积神经网络

卷积神经网络属于机器学习领域当中的深度学习技术,是一类包含了卷积计算并且具有深度结构的前馈神经网络(Feedforward Neural Networks)。由纽约大学教授Yann LeCun在1998年提出,主要应用于语音识别、计算机视觉、自然语言处理等领域。

其本质上是一个采用了局部连接和权值共享方式的多层感知机,包括一般的卷积神经网络(CNN)和深度卷积神经网络(Deep Convolutional Neural Networks, DCNN),通常不做特意区分。一般的卷积神经网络存在浅层结构,但准确性和表现力相对不足,深度卷积神经网络可以自动从大规模的数据中进行特征学习,且具备将结果向同类型的未知数据泛化的能力,是目前最常用的神经网络技术。

2.卷积神经网络原理

2.1 卷积原理

从数学的角度出发,分析数学中定义一种运算,称(f*g)(n)为(f,g)的卷积(Convolution)。其连续的定义为:


其离散的定义为:

其连续和离散具有共同的特征:n=τ+(n-τ),当令x=τ,y=n-τ时,有直线:x+y=n,其图像为如下图:


如果遍历这些直线,就类似于沿直线卷起毛巾的过程。

下面将卷积扩展到二维,有两个R2→R的二元函数f(x,y)和g(x,y),那么令f和g的卷积就是一个新的R2→R的二元函数c(x,y):


其含义为将f在(s,t)上的值乘以g在(x-s,y-t)上的值,再遍历从-∞到+∞全部s和t的值,进行f和g积分意义上的加和,最终得到c在(x,y)上的值(二重积分)。

可以看出这种加和是一种加权求和,即以f为权,(x,y)为中心,将f在(s,t)上的值乘以g距离中心(-s,-t)上的值再相加。

其离散的表示形式为:

2.2 神经元

神经细胞有众多的树突和一个伸长的轴突,不同神经元之间通过树突连接轴突的方式,并通过神经脉冲的传导进行细胞间交流。具体过程为神经细胞A的轴突连接到神经细胞B的树突,传导神经脉冲,神经细胞A根据其树突传递来的信号决定是否通过轴突来向下一个神经细胞C传递信息。

1943年,美国心理学家W.McCulloch和数学家W.Pitts根据生物神经元、生物电和生物化学的运行机理提出了二值神经元的数学模型,即神经细胞机能的简单化的数理模型,被称作莫克罗-彼特氏神经模型(McCulloch-Pitts′Neuron Model),也叫人工神经元模型。


一个人工神经元模型就是对生物神经元的数学建模:


其中X1、X2、X3、…、Xn分别是从其他神经元传入的输入信号,Wi1、Wi2、Wi3、…、Win分别是对应X1、X2、X3、…、Xn的权重。θ表示一个阈值,或称为偏置(Bias),其设置目的是正确将样本分类。神经元当前的输入信号和偏置相加后产生当前神经元的最终处理信号Net,称为净激活或净激励(Net Activation),并作为激活函数或激励函数(Activation Function)f的输入,即f(net),最终得到对应的输出yi。形如:


激活函数f(net)的作用是通过加入非线性因素来解决线性模型的表达和分类能力不足的问题。常见的激活函数有:

1.Linear

Linear是一个线性激活函数:f(x)=∑i xiwi+b。本质上就是对输入的加权求和再加上偏置,所以相对简单,功能较为单一。

由于多个矩阵进行连乘的结果仍是矩阵,类似的,如果一个神经网络中仅使用线性激活函数,那么就只能学习到线性函数。

2.Sigmoid

Sigmoid是在神经网络研究的初始阶段就被投入了广泛使用的一个经典的非线性激活函数,其表达式是一种逻辑斯蒂函数(Logistic Function):


其中x=∑i xiwi+b

这个函数在函数的区域内是完全可导的,输出为0到1范围内的正值(被证实不易于神经网络对收敛的学习),并且对于接近0和1的函数部分,导数无限趋近于0,存在明显的梯度衰减问题。所以现阶段对Sigmod函数的应用已经越来越少。

3.Tanh

通过其图像可以看出Tanh函数旨在克服Sigmoid函数只能取正值的缺陷,将其设计为关于原点对称的双曲正切(hyperbolic tangent)形式:


其中x=∑i xiwi+b。函数的导数取值范围在0到1之间,优于sigmoid的0至1/4,在一定程度上减轻了梯度的消失。但函数的两端仍然存在梯度饱和问题,且计算变得更为复杂。

Tanh的输入和输出能够保持非线性单调上升和下降的关系,符合BP算法网络的梯度求解,容错性好。

4.ReLU (The Rectified Linear Unit)

其公式的表达形式为:


也可以表示为f(x)=max(0,x)。即当输入信号小于0时,函数的输出为0;当输入信号大于0时,函数的输出等于输入值。

ReLU拥有操作简便,耗时少的优点,又具有部分线性的特性,不会出现过饱和现象、减免了梯度消失的问题(函数得到的随机梯度下降法的收敛速度比Sigmoid和Tanh都快)。并且ReLU只需要一个阈值就可以得到激活值,不用和Sigmoid一样进行复杂的指数运算。但其神经元比价脆弱容易失去作用:当神经元接收到非常大的梯度数据流以后,该神经元可能就不再对输入数据进行反馈了,所以在进行训练时要设置一个较小的学习率参数。ReLU是目前用于神经网络领域最常见的激活函数之一。


这就是单个人工神经元的定义。但是早期的单个人工神经元模型甚至无法处理异或等运算,在多个人工神经元发展为神经网络之后逐渐克服了这些问题和种种困难,成为现代人工智能的重要模型。

Read More

Hadoop集群组件配置

Spark集群搭建

首先在scala官网(http://www.scala-lang.org/files/archive/scala-2.10.4.tgz)下载scala语言并解压缩,配置/etc/profile下scala的环境变量

1
2
export SCALA_HOME=/usr/local/scala
export PATH=$PATH:${SCALA_HOME}/bin

环境变量成功生效后进行测试,输入15*15,返回225,成功


接下来到spark官网(http://archive.cloudera.com/cdh5/cdh/5/spark-1.5.0-cdh5.6.0.tar.gz)下载Spark包,继续配置环境变量

1
2
export SPARK_HOME=/usr/local/soft/spark-1.6.0-bin-hadoop2.6
export PATH=$PATH:${SPARK_HOME}/bin

完成后继续配置${SPARK_HOME}/conf/spark-env.sh


配置{SPARK_HOME}/conf/ slaves,在vi编辑器中添加node节点,在将程序分发给node节点

1
2
scp -r spark-1.6.0-bin-hadoop2.6. root@node1:/usr/local/soft/
scp -r spark-1.6.0-bin-hadoop2.6. root@node2:/usr/local/soft/


可以通过./start-all.sh命令来启动spark集群


可也有通过节点来启动:

· 通过sbin/start-master.sh启动主节点
· 通过sbin/start-slave.sh 192.168.218.141:8070等启动node节点


可以执行/bin/run-example SparkPi 10 > Sparkpilog.txt运行spark示例程序


通过jps命令查看启动的java服务,进行验证


Read More

Hadoop入门

Hadoop是一个用Java编写的Apache开源框架,允许使用简单的编程模型跨计算机集群分布式处理大型数据集。Hadoop框架工作的应用程序在跨计算机集群提供分布式存储和计算的环境中工作。Hadoop旨在从单个服务器扩展到数千个机器,每个都提供本地计算和存储。

Hadoop伪分布式搭建

首先创建一台master虚拟机,并克隆node1、node2两台节点机,我的虚拟机集群ip地址分别设置为:

· 192.168.218.141 master

· 192.168.218.142 node1

· 192.168.218.143 node2

到master中设置好ssh,做好主机名与ip地址的映射,修改/etc/hosts下的配置文件,并将完成的hosts文件复制进节点机中

此时可以打开xshell,也可以继续在虚拟机中进行操作

将hadoop的jar包上传到虚拟机中,配置环境变量,并对hadoop下的core-site.xmlhdfs-site.xmlyarn-site.xmlmapred-site.xml文件进行相关配置

完成以后再将hadoop的安装目录分别拷贝到子节点中,检查是否完成集群文件的配置和部署

启动

回到主机中打开hadoop安装目录,执行

1
2
start-dfs.sh
start-yarn.sh

(老版本的”start-all.sh”会提示已过期)

完成hadoop的启动后,在主机和节点机输入jps查看当前运行的java进程




成功后打开浏览器,输入localhost:50700可以进入hadoop初始界面。


Read More

实习项目:CRM管理系统

项目文件代码已存储于github:https://github.com/elbadaernU404/projcode

1.前期准备

首先完成了MySql、JspStudy的安装,测试了数据库的连接,tomcat服务器的部署,以及配置tomcat的动态更新等操作。
接下来主要是做了对Html语法的复习,并尝试对后台登陆界面的编程。
在项目文件的根目录下/web中创建register.html文件进行测试,通过do get的方法发送网页请求,以及添加各类可视化元素,完成注册界面。
同样在/web中创建login.html文件,通过do post的方法发送网页请求(隐藏显示的细节)完成登陆界面。

测试
登陆功能
注册功能

Read More

Python爬虫:豆瓣电影数据

描述

· 目标网站:豆瓣电影网https://movie.douban.com/

· 目标数据1:热门高分电影的名称、类型、评分、总评人数等

· 目标数据2:热门电影《少年的你》影评

· 数据存储:csv、txt

· 爬虫方法:requests、json、xpath、正则表达式

找到网站json,利用xpath、正则表达式等对豆瓣电影数据进行分页爬取,以及对热门电影《少年的你》全部影评进行爬取

movie.douban.com
“少年的你”影评

Read More


Powered by Hexo and Hexo-theme-hiker

Copyright © 2017 - 2024 青域 All Rights Reserved.

UV : | PV :