python爬虫ip限制_简单爬虫,突破IP访问限制和复杂验证码,小总结

简单爬虫,突破复杂验证码和IP访问限制

好吧,看题目就知道我是要写一个爬虫,这个爬虫的目标网站有一些反爬取意识,所以就有了本文了。

我先说说场景吧:

由于工作需要,平时有一大堆数据需要在网上查询,并归档存库。某次,这种任务也给我安排了一份。观察了一网站,我的第一反应就是用爬虫取抓取。这种机械的工作何必人工呢?

由于这家网站有反爬虫的意识,做了些工作,给我的爬虫去爬取数据造成了某些麻烦。

先列举出问题所在:

首当其冲,验证码,该网站采用了数字加中文的简单四则运算作为验证码。

查询目标路径参数经过了加密,我并不能直接通过取路径加参数的方式来直接跳过某些页面。

IP限制,该网站对访问的IP做了访问次数计数限制。经过我的测试,一个纯净IP访问该网站一小时内最多能爬取40个有效数据(这里针对我的抓取目标来说,HTTP请求次数差不多之多200次,但是若在30s内访问次数超过25次HTTP请求,那么这个IP就直接被封掉)

好吧,主要的问题就是这些,一些爬取过程中的小问题,就不列举了。园子里面一大堆的解决方案。这里我主要说的是,验证码和IP限制的问题。

当然,我的解决方案并不是什么高超的技巧。应该都是老路子了。

1、  验证码

原图:

 

 

这种的验证码难度在于字符粘连,字符随机旋转问题。这两种,我分别采用了投影直方图分割、卡壳法来分别切割字符和校正角度。

我首先写了一个工具来测试:

从上面的效果图,各位看官应该能看出,我的方法还是比较简单和传统的,那就是做特征库,通过分割出来的字符去匹配特征库的相似度来判断图片中的文字到底是什么。这里没有使用 第三方的光学识别(OCR ),因为识别汉字感觉识别率还是比较差,而且验证码中的汉字其实并不多,就是几个特定的字符,加减乘除等。所以通过特征库来识别也是绰绰有余了。

关于验证码,我来说说我的一些问题,对于灰度计算和二值化,园子里面有很多算法,但是对于降噪,也就是去干扰线,需要自己根据目标来写特定的算法。我这里是通过削皮的方式来去掉的,每次给所有阴影剥掉一层1px的范围,填充为白色。当然了,我这方法不具备通用性。不同的验证码需要根据观察来用不同的方式来去除。

分割呢,也就是直方图了,其实我的验证码也是可以根据色彩来做单色的直方图,这样来一步完成分割字符和降噪(有这想法,但是没有实际去实现。不过看有些大牛的博客说这样的方法是可行的)。我所了解到的分割方法还有滴水分割,不过我拿了论文资料,可惜看得不是很懂。下面贴了一段简单绘制直方图的方法:

1 //绘制直方图

2 var zftbit = newBitmap(bit4.Width, bit4.Height);3 using (Graphics g =Graphics.FromImage(zftbit))4 {5 Pen pen = newPen(Color.Blue);6 for (int i = 0; i < bit4.Width; i++)7 {8 g.DrawLine(pen, i, bit4.Height - YZhiFang[i] * 2, i, bit4.Height);9 }10 //阀值

11 g.DrawLine(new Pen(Color.Red), 0, bit4.Height - 2, bit4.Width, bit4.Height - 2);12 }13 p_zft.Image = zftbit;

绘制直方图

关于随机旋转的字符问题,我的做法是,将验证码中的字符分割成独立单位后,进行正负30度旋转,每旋转一次,计算一次投影宽度,由于我们的字体基本上都是‘方块字’,所以呢,在旋转的时候,最小宽度肯定是‘摆正’了的,不过,这里有个小问题,那就是若源字符旋转超过45°,我们将字横着放置的时候,其宽度也是最小的。不过我们让机器多学习几次,将四个方向摆放的图形都学习了,就可以了。这就是卡壳法了。

2、IP限制问题

这里我用了最无赖也是最无解的方法来解决的。我直接通过切换访问的代理来突破,这里没有丝毫技术性含量。挂上代理后,去访问目标网站,根据返回的结果判断代理是否还有效。若是无效了,将当前查询目标回滚一次,并切换代理就行了。

3、爬虫

主角爬虫来了,我最早设计的爬虫是不控制时间的连续访问的,这导致代理消耗的特别快。所以不得不想办法解决这个问题。另外由于没有专门的爬虫服务器,我只能通过办公室的电脑来完成这项任务。由此,我设计了一个总线式爬虫。

我写了一个爬虫服务端和一个爬虫客户端,服务端当做中央处理器,来分配计算量,客户端爬虫用来抓取数据。这样的情况下,各个客户端执行的速度其实是不一样的,请求响应又快又慢,验证代理是否有效也需要时间,所有,客户端爬虫完成任务的时间肯定不一样,所以我安排了这样一台电脑做作为中央处理器,分批次,小剂量的去分发任务列表。并接收客户端回传的结果,等完成所有任务之后统一导出或者进行写入数据库等其他操作。

爬虫节点

每个节点上的爬虫,给17个线程去跑,10个做代理IP的验证,7个爬数据。若是给10台办公室的笔记本安装软件,一起去爬数据,那么,就相当于 70人/秒 的速度在访问这个网站。至此,效率问题也解决了。

总线

总线方面,将任务列表根据下面的节点数进行分配(上图是之前截的图,之前是均分出去,后来发现均分的客户端并不是同时完成,有的快有的慢,结果快的弄完了,就空闲了,慢的还在慢吞吞的跑,所以,之后进行了小剂量分配,变相的达到动态的安排任务量)。

后记

文章到此就基本上结束了,代码不多,我主要数我的制作思路,因为我的的这个并不具备通用性,验证码家家基本都不一样(一些极度简单的规规矩矩的纯数字或字母验证码不算,这类验证码跟没有一样)。

2018年09月30日

多年后来更新这篇文章:当年萌新的技术缺点

1. 验证码识别的方式太辣鸡,算法复杂度O(n^2),辣鸡中的战斗鸡

2. 采用分布式的思维来做,这点,我很肯定当年的萌新,毕竟是自己想出来的提速方法嘛。也想到了队列这个概念,现在可以对这里的队列重新定义一下,可以采用RabbitMQ等中间件来完成分发任务,更可靠也更高效。

3. 感谢当年萌新的彻夜奋斗!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/431453.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

php使用双引号,PHP编程双引号怎么使用

PHP编程双引号怎么使用PHP用单引号代替双引号来包含字符串&#xff0c;这样做会更快一些。因为PHP会在双引号包围的字符串中搜寻变量&#xff0c;单引号则 不会&#xff0c;注意&#xff1a;只有echo能这么做&#xff0c;它是一种可以把多个字符串当作参数的“函数”(译注&…

IOS UITextView自适应高度

LOFTER app需要实现了一个类似iPhone短信输入框的功能&#xff0c;它的功能其实蛮简单&#xff0c;就是&#xff1a;【UITextView的高度随着内容高度的变化而变化】。实现思路应该是&#xff1a; 在UITextView的textChanged事件响应代码里计算输入内容的高度&#xff0c;然后如…

python获取mac窗口程序内容_在Mac OS X中获取当前活动窗口/文档的标题

在Objective-C&#xff0c;简单的答案&#xff0c;用少量可可和大多Carbon Accessibility API是&#xff1a;// Get the process ID of the frontmost application.NSRunningApplication* app [[NSWorkspace sharedWorkspace]frontmostApplication];pid_t pid [app processId…

php实战搭建博客,yii2项目实战-博客管理平台的搭建

作者&#xff1a;白狼 出处&#xff1a;http://www.manks.top/document/yii2-blog-manage.html 本文版权归作者&#xff0c;欢迎转载&#xff0c;但未经作者同意必须保留此段声明&#xff0c;且在文章页面明显位置给出原文连接&#xff0c;否则保留追究法律责任的权利。相信看了…

ACM学习历程—HDU2068 RPG的错排(组合数学)

Description 今年暑假杭电ACM集训队第一次组成女生队,其中有一队叫RPG,但做为集训队成员之一的野骆驼竟然不知道RPG三个人具体是谁谁。RPG给他机会让他猜猜&#xff0c;第一次猜&#xff1a;R是公主&#xff0c;P是草儿&#xff0c;G是月野兔&#xff1b;第二次猜&#xff1a;R…

python训练手势分类器_机器学习零基础?手把手教你用TensorFlow搭建图像分类器|干货...

编者按&#xff1a;Pete Warden是TensorFlow移动团队的技术负责人。曾在Jetpac担任首次技术官。Jetpac的深度学习技术经过优化&#xff0c;可在移动和嵌入式设备上运行。该公司已于2014年被谷歌收购。Pete还曾在苹果公司从事GPU优化领域的图像处理工作&#xff0c;并为OReilly撰…

汉军Hundre考勤数据库数据表分析总结

ar-ATT为考勤刷卡数据库 Att-carRecord为刷卡流水&#xff0c;但是插入时需要根据workrecord表中数据进行判断 ATT-workrecord为运算后明细表存放位置&#xff0c;每次运算后重新生成。 刷卡数据更改方法&#xff1a; 查询序列&#xff1a;SELECT * FROM [AR_att].[dbo].[ATT_…

python内存消耗大吗_如何减少python内存的消耗?

标签&#xff1a;Python 打算删除大量涉及像C和C语言那样的复杂内存管理。当对象离开范围&#xff0c;就会被自动垃圾收集器回收。然而&#xff0c;对于由Python 开发的大型且长期运行的系统来说&#xff0c;内存管理是不容小觑的事情。在这篇博客中&#xff0c;我将会分享关于…

php invalid access,PHP出错消息PHP has encountered an Access Violation at XXXXXXXX 如何解决?...

1、是否zend所需的dll文件所在目录给的权限不够&#xff0c;必须有读取和运行的权限2、如果使用的是windows系统&#xff0c;是否设置过应用池&#xff0c;比如池https://anlijun.co中限制了什么

java class load 类加载

1:what is it jvm把描述类的数据从class字节码文件加载到内存&#xff0c;并对数据进行校验、解析、初始化&#xff0c;最终成为jvm直接使用的数据类型 1、ClassNotFoundExcetpion   我们在开发中&#xff0c;经常可以遇见java.lang.ClassNotFoundExcetpion这个异常&#xf…

python回溯方法的模板_Python基于回溯法子集树模板解决0-1背包问题实例

本文实例讲述了Python基于回溯法子集树模板解决0-1背包问题。分享给大家供大家参考&#xff0c;具体如下&#xff1a;问题给定N个物品和一个背包。物品i的重量是Wi,其价值位Vi &#xff0c;背包的容量为C。问应该如何选择装入背包的物品&#xff0c;使得放入背包的物品的总价值…

debian执行php网页,如何在Debian上安装和使用PHP Composer

php composer是一个包管理工具&#xff0c;它消除了手动维护应用程序的PHP包的麻烦&#xff0c;可以使用composer轻松安装所有必需的包。本篇文章将介绍在Debian系统上安装和配置PHP Composer的方法。1、条件shell使用sudo权限访问正在运行的debian系统。必须安装和配置5.3或更…

python图灵测试_最前沿:基于GAN和RL的思想来训练对话生成,通过图灵测试可期!...

PS&#xff1a;本文分析略深&#xff0c;需要一定的RL和GAN的基础。前两天&#xff0c;Stanford的NLP小组出了一篇神经网络对话生成的论文&#xff1a;标题就是使用对抗学习来做神经对话生成。这个idea非常的赞&#xff01;在我看来是通往图灵测试的正确一步。以前的对话生成&a…

java map 实现 序列化,MapReduce序列化

序列化就是把内存中的对象转换成字节序列以便于存储到磁盘(持久化)和网络传输。反序列化就是将字节序列或者是持久化的数据转换成内存中的对象。内存中的对象只能本地进程使用&#xff0c;断掉后就消失了&#xff0c;也不能被发送到网络上的另一台机器&#xff0c;序列化可以将…

安装php时,make步骤报错make: *** [sapi/fpm/php-fpm] Error 1

安装PHP过程中&#xff0c;make步骤报错&#xff1a;(集中网络上各种解决方法) (1)-liconv -o sapi/fpm/php-fpm /usr/bin/ld: cannot find -liconv collect2: ld returned 1 exit status make: *** [sapi/fpm/php-fpm] Error 1 [rootlocalhost php-5.4.5]# 初步定位是iconv的问…

JAVA_if或者怎么用,Java If语句

Java教程 - Java If语句Java if语句用于根据条件执行一个代码块。Java If语句下面是Java if语句的最简单形式:if(condition)statement;condition是一个布尔表达式。如果condition是true那么执行语句。如果condition是false&#xff0c;那么绕过语句。以下代码根据an的值输出消息…

iOS开发——高级技术本地化与国际化详解

本地化与国际化详解效果如下&#xff1a;英语&#xff1a; 中文&#xff1a; 具体实现如下&#xff1a;一。先做准备&#xff1a;设置程序本地化在xcode点击程序图标…

hog特征提取python代码_hog特征提取-python实现

【转载自 https://blog.csdn.net/ppp8300885/article/details/71078555】全部代码&#xff1a;importcv2importnumpy as npimportmathimportmatplotlib.pyplot as pltclassHog_descriptor():def __init__(self, img, cell_size16, bin_size8):self.imgimgself.img np.sqrt(img …

matlab 矢量化,matlab矢量化编程简要

一、基本技术1)MATLAB索引或引用(MATLAB Indexing or Referencing)在MATLAB中有三种基本方法可以选取一个矩阵的子阵。它们分别是下标法&#xff0c;线性法和逻辑法(subscripted, linear,andlogical)。1.1)下标法非常简单&#xff0c;看几个例子就好。A 6:12;A([3,5])ans 8 10…

Hadoop-HBASE案例分析-Hadoop学习笔记二

之前有幸在MOOC学院抽中小象学院hadoop体验课。 这是小象学院hadoop2.X概述第八章的笔记 主要介绍HBase&#xff0c;一个分布式数据库的应用案例。 案例概况&#xff1a; 1&#xff09;时间序列数据库(OpenTSDB) 用HBase储存时间序列数据&#xff0c;每时每刻都在解决&#xff…