首页 文章 精选 留言 我的

精选列表

搜索[python],共10000篇文章
优秀的个人博客,低调大师

22、Python快速开发分布式搜索引擎Scrapy精讲—scrapy模拟登陆和知乎倒立文字验证码识别

转自: http://www.bdyss.cn http://www.swpan.cn 第一步。首先下载,大神者也的倒立文字验证码识别程序 下载地址:https://github.com/muchrooms/zheye 注意:此程序依赖以下模块包 Keras==2.0.1 Pillow==3.4.2 jupyter==1.0.0 matplotlib==1.5.3 numpy==1.12.1 scikit-learn==0.18.1 tensorflow==1.0.1 h5py==2.6.0 numpy-1.13.1+mkl 我们用豆瓣园来加速安以上依赖装如: pipinstall-ihttps://pypi.douban.com/simpleh5py==2.6.0 如果是win系统,可能存在安装失败的可能,如果那个包安装失败,就到 http://www.lfd.uci.edu/~gohlke/pythonlibs/ 找到win对应的版本下载到本地安装,如: pipinstallh5py-2.7.0-cp35-cp35m-win_amd64.whl 第二步,将者也的,验证码识别程序的zheye文件夹放到工程目录里 第三步,爬虫实现 start_requests()方法,起始url函数,会替换start_urls Request()方法,get方式请求网页 url=字符串类型url headers=字典类型浏览器代理 meta=字典类型的数据,会传递给回调函数 callback=回调函数名称 scrapy.FormRequest()post方式提交数据 url=字符串类型url headers=字典类型浏览器代理 meta=字典类型的数据,会传递给回调函数 callback=回调函数名称 formdata=字典类型,要提交的数据字段 response.headers.getlist('Set-Cookie')获取响应Cookiesresponse.request.headers.getlist('Cookie')获取请求Cookies #-*-coding:utf-8-*- importscrapy fromscrapy.httpimportRequest,FormRequest importre classPachSpider(scrapy.Spider):#定义爬虫类,必须继承scrapy.Spider name='pach'#设置爬虫名称 allowed_domains=['zhihu.com']#爬取域名 #start_urls=['']#爬取网址,只适于不需要登录的请求,因为没法设置cookie等信息 header={'User-Agent':'Mozilla/5.0(WindowsNT10.0;WOW64;rv:54.0)Gecko/20100101Firefox/54.0'}#设置浏览器用户代理 defstart_requests(self):#起始url函数,会替换start_urls """第一次请求一下登录页面,设置开启cookie使其得到cookie,设置回调函数""" return[Request( url='https://www.zhihu.com/#signin', headers=self.header, meta={'cookiejar':1},#开启Cookies记录,将Cookies传给回调函数 callback=self.parse )] defparse(self,response): #响应Cookies Cookie1=response.headers.getlist('Set-Cookie')#查看一下响应Cookie,也就是第一次访问注册页面时后台写入浏览器的Cookie print('后台首次写入的响应Cookies:',Cookie1) #获取xsrf密串 xsrf=response.xpath('//input[@name="_xsrf"]/@value').extract()[0] print('获取xsrf密串:'+xsrf) #获取验证码 importtime t=str(int(time.time()*1000)) captcha_url='https://www.zhihu.com/captcha.gif?r={0}&type=login&lang=cn'.format(t)#构造验证码请求地址 yieldRequest(url=captcha_url,#请求验证码图片 headers=self.header, meta={'cookiejar':response.meta['cookiejar'],'xsrf':xsrf},#将Cookies和xsrf密串传给回调函数 callback=self.post_tj ) defpost_tj(self,response): withopen('yzhm.jpg','wb')asf:#打开图片句柄 f.write(response.body)#将验证码图片写入本地 f.close()#关闭句柄 #---------------------------者也验证码识别----------------------- fromzheyeimportzheye#导入者也倒立文字验证码识别模块对象 z=zheye()#实例化对象 positions=z.Recognize('yzhm.jpg')#将验证码本地路径传入Recognize方法识别,返回倒立图片的坐标 #print(positions)#默认倒立文字的y坐标在前,x坐标在后 #知乎网要求的倒立文字坐标是x轴在前,y轴在后,所以我们需要定义一个列表来改变默认的,倒立文字坐标位置 pos_arr=[] iflen(positions)==2: ifpositions[0][1]>positions[1][1]:#判断列表里第一个元祖里的第二个元素如果大于,第二个元祖里的第二个元素 pos_arr.append([positions[1][1],positions[1][0]]) pos_arr.append([positions[0][1],positions[0][0]]) else: pos_arr.append([positions[0][1],positions[0][0]]) pos_arr.append([positions[1][1],positions[1][0]]) else: pos_arr.append([positions[0][1],positions[0][0]]) print('处理后的验证码坐标',pos_arr) #-------------者也验证码识别结束-------- iflen(pos_arr)==2: data={#设置用户登录信息,对应抓包得到字段 '_xsrf':response.meta['xsrf'], 'password':'279819', 'captcha':'{"img_size":[200,44],"input_points":[[%.2f,%f],[%.2f,%f]]}'%( pos_arr[0][0]/2,pos_arr[0][1]/2,pos_arr[1][0]/2,pos_arr[1][1]/2),#因为验证码识别默认是400X88的尺寸所以要除以2 'captcha_type':'cn', 'phone_num':'15284816568' } else: data={#设置用户登录信息,对应抓包得到字段 '_xsrf':response.meta['xsrf'], 'password':'279819', 'captcha':'{"img_size":[200,44],"input_points":[[%.2f,%f]]}'%( pos_arr[0][0]/2,pos_arr[0][1]/2), 'captcha_type':'cn', 'phone_num':'15284816568' } print('登录提交数据',data) print('登录中....!') """第二次用表单post请求,携带Cookie、浏览器代理、用户登录信息,进行登录给Cookie授权""" return[scrapy.FormRequest( url='https://www.zhihu.com/login/phone_num',#真实post地址 meta={'cookiejar':response.meta['cookiejar']},#接收第传过来的Cookies headers=self.header, formdata=data, callback=self.next )] defnext(self,response): #请求Cookie Cookie2=response.request.headers.getlist('Cookie') print('登录时携带请求的Cookies:',Cookie2) jieg=response.body.decode("utf-8")#登录后可以查看一下登录响应信息 print('登录响应结果:',jieg) print('正在请需要登录才可以访问的页面....!') """登录后请求需要登录才能查看的页面,如个人中心,携带授权后的Cookie请求""" yieldRequest( url='https://www.zhihu.com/people/lin-gui-xiu-41/activities', headers=self.header, meta={'cookiejar':True}, callback=self.next2 ) defnext2(self,response): #请求Cookie Cookie3=response.request.headers.getlist('Cookie') print('查看需要登录才可以访问的页面携带Cookies:',Cookie3) leir=response.xpath('/html/head/title/text()').extract()#得到个人中心页面 print('最终内容',leir) #print(response.body.decode("utf-8")) 【转载自:http://www.lqkweb.com】

优秀的个人博客,低调大师

Python 的 with 到底在管什么?拆开上下文管理器:__exit__ 返回值决定生死,异常从 yield 灌进去

**结论先行:with 不是语法糖版的 try/finally——它把「资源生命周期」拆成了两次函数调用:__enter__ 拿资源、__exit__ 还资源,而 __exit__ 的返回值就是异常的生杀大权:返回 True,异常被当场吞掉;返回 False 或 None,异常原样穿透。更反直觉的是 @contextmanager 那一套:with 块里抛出的异常不是「被 except 抓到」,而是被 throw 进生成器、从 yield 那个点灌进去的。实测这套协议本身只要 353 纳秒,但一个没关掉的文件句柄能拖垮整个服务。这篇用 6 组实验把协议拆到底。** --- ## 1. 两次调用:with 的全部秘密 **把 with 语句编译成字节码,结构极其简单**: ```javascript 1 BEFORE_WITH # 调用 __enter__,结果压栈(就是 as 绑定的值) 2 ... # with 块体 3 LOAD_CONST None 4 PUSH_EXC_INFO # 记录:如果块体炸了,异常信息在这里 5 WITH_EXCEPT_START# 调 __exit__(type, val, tb),看返回值决定吞不吞 6 POP_EXCEPT # 块体正常结束也走这里:__exit__(None, None, None) ``` **正常路径**:`__enter__()` → 块体 → `__exit__(None, None, None)`。 **异常路径**:块体炸了 → `__exit__(异常类型, 异常值, traceback)` → 返回真值就地吞掉,返回假值原样抛出。 实测 tracer 类的调用序列完全吻合: ```javascript __enter__ called body running __exit__ called, exc = None ``` ## 2. __exit__ 的返回值 = 异常的生杀大权 **这是整个协议里唯一需要记住的规则**。三个实测场景: |`__exit__` 返回|块体抛 `ValueError`|实测结果| | --- | --- | --- | |`True`|吞掉|`suppress __exit__ exc = ValueError` → 后续代码继续执行| |`False`|穿透|`reraise __exit__ exc = KeyError` → 外层 try 抓到 KeyError| |`None`(默认)|穿透|同 False,异常原样抛出| **这就是 **`contextlib.suppress(FileNotFoundError)`** 的全部实现原理**——它的 `__exit__` 就是一句 `return issubclass(exc_type, self._exceptions)`。**一个返回值,把一个 try/except/pass 三件套压缩成了 with 一行**。 ## 3. @contextmanager:yield 是 enter/exit 的分界线 `@contextlib.contextmanager` **把一个生成器函数变成上下文管理器,切面就一刀**: ```javascript @contextlib.contextmanager def res(tag): print('enter: acquire', tag) # yield 之前的代码 = __enter__ try: yield tag # ← as 绑定的值;块体在这里跑 finally: print('exit: release', tag) # yield 之后的代码 = __exit__ ``` 实测输出:`enter: acquire DB` → `using DB` → `exit: release DB`。****yield 之前是拿资源,yield 之后是还资源**,with 块体整个被塞进 yield 的暂停窗口里。** ## 4. 异常不是被 except 抓的,是被 throw 进去的 这是 @contextmanager 最容易被误解的地方。看这组实测: ```javascript @contextlib.contextmanager def res2(): try: yield except ValueError: print('gen caught ValueError (via throw)') # ← 这一行会打印 finally: print('gen finally') with res2(): raise ValueError('x') ``` 输出证实:`gen caught ValueError (via throw)` 和 `gen finally` 都打印了。 ****块体里的 ValueError 不是「冒泡到 except」**——它是被 `gen.throw(ValueError)` 从 yield 那个点直接灌进生成器的**。**所以写在 yield 后面的 except 能抓到 with 块体的异常**,**写在 yield 前面的代码(enter 阶段)想抓也抓不到**——那时块体还没开始跑。 这也是为什么上下文管理器里写「清理」要放在 finally 里:异常从 yield 灌进来,finally 是唯一保证执行的收尾。 ## 5. 异常被吞的三种死法,逐一排雷 用 @contextmanager 时踩坑的经典三连: |坑|现象|根因| | --- | --- | --- | |yield 不在 try 里|块体一抛异常,finally 不执行,资源泄漏|yield 裸奔,throw 直接掀翻生成器| |yield 返回值为 None|`with res() as r` 拿到 None|忘了 `yield value`,as 绑了个空| |enter 阶段就抛异常|块体不执行,但 `__exit__` 也不会调|进屋子就塌了,没人负责拆屋| **规律:拿资源的代码(yield 前)要自含清理或让它自然失败;还资源的代码(yield 后)必须包在 finally 里。** ## 6. 协议本身 353 纳秒,但别在热点里开火锅店 实测 100 万次 with 的开销: |写法|每次耗时| | --- | --- | |`with noop: pass`(空协议)|**353 ns**| |裸 `try/finally: pass`|60 ns| |`with open('NUL') as f: pass`|42 250 ns| 两个结论:****协议本身(两次方法调用+异常帧)约 300 ns**,约为裸 try/finally 的 6 倍;但真正的开销从来不在协议——open 的 42 微秒全是系统调用**。在每秒百万次的循环里开合 with 确实该优化(提到循环外),但绝大多数场景,with 的 353 ns 连零头都算不上。为了「性能」把 with 拆成裸 try/finally,是用可维护性换 290 纳秒的亏本买卖**。** --- **一句话收尾:with 的本质是「两次调用加一个返回值」——__enter__ 拿资源、__exit__ 还资源、返回值决定异常生死;@contextmanager 把这一切架在 yield 上:异常不是被抓的,是从 yield 灌进去的。353 纳秒的协议费,买的是资源生命周期永远不会漏的保证。**

优秀的个人博客,低调大师

【k哥爬虫普法】Python程序员爬取视频资源13万部,一分钱没挣,获刑2年!

我国目前并未出台专门针对网络爬虫技术的法律规范,但在司法实践中,相关判决已屡见不鲜,K 哥特设了“K哥爬虫普法”专栏,本栏目通过对真实案例的分析,旨在提高广大爬虫工程师的法律意识,知晓如何合法合规利用爬虫技术,警钟长鸣,做一个守法、护法、有原则的技术人员。 案情介绍 2017年以来,被告人王世杰工作期间,为利用自己所学计算机网络技术建立网站赚钱,租用云服务器开办了一个名为“酷奇XX视频”的视频网站。利用爬虫技术在互联网上爬取未经著作权人授权许可的电影、电视剧、综艺、动漫等各类视频资源,包括《流浪地球》、《复仇者联盟4》、《大闹天空》等最新影视剧,以及淫秽主播视频表演等视频。 此后,王世杰通过在视频网站网页上挂载“广告位招租”招商广告,招商广告中载明自己的QQ号码,伺机通过视频资源牟利。且王世杰通过网站设置了一个会员注册信息,用户可以用手机号或者邮箱账号注册成为会员,会员可以通过在线支付现金购买充值卡,1元兑换1积分,不同积分可升级为阶梯式包时段的会员,享受该网站提供的各种VIP会员服务。 2019年5月8日,勉县公安局受案后,民警依法对“酷奇XX视频”网站的信息进行了在线提取,其中提取各类涉嫌侵犯著作权影视作品601部,疑似淫秽物品视频238部。 同年5月18日,阿里云公司工作人员因发现“酷奇XX视频”网站信息与备案不符,将“酷奇XX视频”网站关停。 同年5月21日,经汉中市公安局对从“酷奇XX视频”网站中提取的45部福利视频鉴定,意见为:送检的2张DVD光盘内视频文件名称01至45的45部视频录像为淫秽及色情物品。 同年5月30日,民警在上海市易果电子商务有限公司办公室将被告人王世杰抓获,在其家中扣押黑色台式组装电脑主机一台,并依法提取了电子数据。 同年9月6日,经汉中市公安局对从“酷奇XX视频”网站中提取的总计238部福利视频鉴定,意见为:移动硬盘内视频文件名称编号为001至238的238部视频录像为淫秽及色情物品。 截止“酷奇XX视频”网站被关停时,该网站共有会员55人,提供各类视频总计13万余部,其中有电影5.1万余部,电视剧2.2万余部,综艺2.3万余部,动漫2.4万余部等,福利其它9085部,其中已提取固定视频839部(含福利视频238部,普通电影视频601部)。 截止案发,未发现有注册会员支付款项。同时,网站转载的部分视频中存在镶嵌式广告,在案件侦查过程中也没有发现王世杰有实际广告收入。 公诉机关据此认为被告人王世杰的行为构成侵犯著作权罪、传播淫秽物品罪,建议对其判处二年以上三年以下有期徒刑,可适用缓刑,并处罚金。 被告人王世杰对起诉书指控的犯罪事实无异议,自愿认罪,请求对其从轻处罚。 供辩情况 本案重点在供述的时候,辩护人对犯罪事实无异议,但辩称:1、本案中,被告人王世杰没有营利目的;2、对公诉机关指控被告人王世杰构成侵犯著作权罪有异议。建立链接不同于复制发行,亦不属于提供作品,王世杰没有侵犯著作权的主观故意和客观行为,且侵犯著作权罪是数额犯,王世杰并没有实际获利,故不构成侵犯著作权罪;3、被告人王世杰没有传播淫秽物品的故意,只是因为没有做好网站的管理工作,疏忽大意。爬虫技术是对访问行为的模仿,无法自我识别、甄别淫秽视频; 但实际上法院也一一驳回了 因为法院认为被告人在网站网页上挂载“广告位招租”窗口,招商广告中载明自己的QQ号码为联系方式;还在网站中设置了会员注册、在线支付、积分兑换等,其具有营利目的、且其行为属于复制发行。以营利为目的,未经著作权人、录音录像制作者许可,通过互联网向公众传播他人电影、电视作品601部,情节严重,其行为构成侵犯著作权罪; 其次,被告人王世杰作为视频网站的创建人和管理者,理应加强网站的管理和维护,其在采用爬虫技术时,未对相关影视进行甄别,对淫秽视频的传播持放任态度,其主观上具有传播淫秽物品的故意,利用互联网传播淫秽音像视频238部,情节严重,其行为亦构成传播淫秽物品罪 判决情况 被告人王世杰犯侵犯著作权罪,判处有期徒刑一年零六个月,并处罚金人民币5000元;犯传播淫秽物品罪,判处有期徒刑八个月。 二罪并罚,决定执行有期徒刑二年,缓刑二年零六个月,并处罚金人民币5000元。 反思总结 很明显,案例中的当事人就是想爬一些电影视频资源放到自己网站,通过会员制度和广告来盈利,除了这种爬取视频资源的情况,还有不少人通过爬虫技术爬取技术博主的原创文章,放到自己的网站上,这种做法通常也会在网站上植入广告来盈利,还有的是为了给网站做 SEO 优化,提高网站权重,也有的给文章设置付费内容、扫码关注公众号才解锁内容等,这种未经过原作者允许进行恶意采集并盈利的行为,无疑都是侵犯著作权的,也是可以被判刑的。 不少人想将爬虫作为副业赚钱,也有很多人信奉“技术无罪”,要知道“技术无罪”论,自从快播案后就是不存在的,利用爬虫赚钱,应走正道,目的和手段都要合法合规,也一定要注意是否侵犯了别人的隐私权和著作权,切莫心存歪念,因小失大。当然利用爬虫技术传播淫秽物品更是我们不能触及的红线! 常见的“仅用于内部学习交流,不得传播”的避风港原则,在人人影视案之后也不存在了,因此公司如果有类似的项目,技术和运营团队都有义务对所爬取的内容进行甄别,利用人工智能、NLP等技术,对文本、图片、视频进行合法性鉴别,甚至要有专门的数据治理部门,对于违法内容理应立即销毁。 爬虫技术基本上来说是一个加速便捷工具,如果你业务不合规,手动执行都是违法的,那么大规模高效获取只会加速灭亡,因此在使用效率技术前一定要想清楚自己业务的商业模式是否合法合规,要么就不做,要做就得加强合规建设。

资源下载

更多资源
Mario

Mario

马里奥是站在游戏界顶峰的超人气多面角色。马里奥靠吃蘑菇成长,特征是大鼻子、头戴帽子、身穿背带裤,还留着胡子。与他的双胞胎兄弟路易基一起,长年担任任天堂的招牌角色。

Spring

Spring

Spring框架(Spring Framework)是由Rod Johnson于2002年提出的开源Java企业级应用框架,旨在通过使用JavaBean替代传统EJB实现方式降低企业级编程开发的复杂性。该框架基于简单性、可测试性和松耦合性设计理念,提供核心容器、应用上下文、数据访问集成等模块,支持整合Hibernate、Struts等第三方框架,其适用范围不仅限于服务器端开发,绝大多数Java应用均可从中受益。

Rocky Linux

Rocky Linux

Rocky Linux(中文名:洛基)是由Gregory Kurtzer于2020年12月发起的企业级Linux发行版,作为CentOS稳定版停止维护后与RHEL(Red Hat Enterprise Linux)完全兼容的开源替代方案,由社区拥有并管理,支持x86_64、aarch64等架构。其通过重新编译RHEL源代码提供长期稳定性,采用模块化包装和SELinux安全架构,默认包含GNOME桌面环境及XFS文件系统,支持十年生命周期更新。

Sublime Text

Sublime Text

Sublime Text具有漂亮的用户界面和强大的功能,例如代码缩略图,Python的插件,代码段等。还可自定义键绑定,菜单和工具栏。Sublime Text 的主要功能包括:拼写检查,书签,完整的 Python API , Goto 功能,即时项目切换,多选择,多窗口等等。Sublime Text 是一个跨平台的编辑器,同时支持Windows、Linux、Mac OS X等操作系统。

用户登录
用户注册