业务需求:拦截一切不登录的盗链URL,除了问卷调查,可以给任意用户填写和提交意外。
问题重现:表单提交过程中返回302状态码,我就觉得很奇怪。在网上搜索了一下,302代表的是重定向。
令我疑惑的是:我访问登录都可以,为什么提交保存问卷的时候会报302错误。
排查:先从ajax发请求前打console.log,然后在controll方法上打断点,发现完全到不了断点,直接报302错误。
最终想到了项目中用shiro管理权限了,把所有的url请求都给拦截了,所以没法提交报告。
最终,到shiro中将请求URL加上,就解决了。
踩过这个坑后,以后在遇到302错误,我就会首先想到是不是URL被拦截了。这样也可以加快排查速度。
作者 向右奔跑 关注
这是我学习Python爬虫第30天的笔记。
模拟登录是爬取某些站点内容的一个关键,有些网站(特别是论坛类),不登录的话,一个数据也拿不到。
模拟登录有这样几个关键:
- 弄清楚登录的url
一些网站打开出现登录的页面,地址栏大多数不是登录提交表单的url。 -
提交登录表单的字段
登录页面的url和登录表彰的字段名获取的方式有两种:
1) 分析页面源代码,找到表单标签及属性。适应比较简单的页面,或者对网页代码,js非常熟悉。
2) 采用抓包工具,查看提交的url和参数,如Chrome的开发者工具中的Network, Fiddler等。这种方式简单粗暴、快速。尤其适应页面比较复杂,登录时经过了几次跳转的。 -
登录以后去往页面的url
这个不是必须的,因为一般都有登录后默认打开的页面,或者你所需要取数据的页面是明确的。但是如果对于第三方登录来讲,这个参数就是必要的。
知道了登录url, 表单的参数后,通过提交参数的方式来实现登录,不难。不是本文讨论的重点。
params = {'uname':'kitty','upass':'hello'}r = requests.post("http://xxx.org/post", data=params)
一些站点的登录流程还是比较复杂,如代码封装在js中,登录时经过了跳转。那采用以上的方式来实现登录就比较复杂。即使用抓包拿到登录url,表单参数,这时的登录一般还附加了一些其他参数,需要一一构造出来,有的如时间戳等等。
有没有一种比较简单的方式,来成功实现爬虫模拟登录的,然后方便抓取到数据?Cookie就是这样一种方式。不需要知道登录url, 不需要知道登录表单的字段名,以及还需要哪些其他参数。
我以QQ群论坛来说明使用Cookie实现模拟登录,然后抓取数据。打开就是加载的登录div。
![](https://i-blog.csdnimg.cn/blog_migrate/a78cc119bad4eedf89576d2334b1da15.webp?x-image-process=image/format,png)
以下两种方式,都需要首先拿到Cookie,可以使用Chorme开发者工具,或者Fiddler,在目标网站上使用用户名和密码登录一下,就拿到Cookie了。
![](https://i-blog.csdnimg.cn/blog_migrate/ef8b44fcc8db6852c29009803b7b4179.webp?x-image-process=image/format,png)
一、用requests发送请求,实现模拟登录
使用requests发送请求时,把cookie作为参数传递进来就可以了。
构造Cookie:
cookie = {'Cookie': 'qm_username=137958873x0; qm_sid=8a4cce2f4413b4a5c9981093942b3f6f,qMUZrWmt0Z0XQbVZWKlNBZXUzT0xCSXJNRHNXU1NDVzd6MXZFQjJSbGZxMF8.; RK=/jt+Uh72a5; pgv_pvid=2786550760; pgv_info=ssid=s5861035317; ptui_loginuin=1379588730; ptisp=ctc; ptcz=e3d339f47c356076793ff4c270b572e35ed69746057039ee2e78677e391793b9; pt2gguin=o1379588730; uin=o1379588730; skey=@ssNmMQP3p; p_uin=o1379588730; p_skey=2w78648Kd9wuwxK9lsiDM02MQFJfSIhEuxhhE*aH-SU_; pt4_token=aGGiHcty94vO0iC8mxQ*OgkHOI6fZmdzQCxsb-baX1U_'}
发达请求时,传递Cookie
html = requests.get(url,cookies=cookie).content
详细可参考,《用Python玩转QQ群论坛》
二、用Scrapy实现模拟登录
在Scrapy中Cookie登录的步骤跟上面一样,但是在实现过来中,却遇到很多困难,一直困扰我,而且在Scrapy中提示不多,如请求被禁止:
getting Forbidden by robots.txt: scrapy
总结一下Scrapy中实现Cookie登录的方法:
1)Cookie的写法不一样:
![](https://i-blog.csdnimg.cn/blog_migrate/807f0869fea5a2f4b9f76fcdd241031e.webp?x-image-process=image/format,png)
注意,验证登录写在start_requests()方法中,传递cookie参数。
return [FormRequest("http://qgc.qq.com/309o916014x/",cookies=cookies,callback=self.parse)]
2) 在settings.py中的配置,增加:
ROBOTSTXT_OBEY=False
再次启动爬虫,成功!还是同样的页面,抓取到数据。
![](https://i-blog.csdnimg.cn/blog_migrate/78ca9a252f773cd187d64361d6e2c9a7.webp?x-image-process=image/format,png)
总结一下,使用Cookie登录的好处:
不需要知道登录url和表单字段以及其他参数,不需要了解登录的过程和细节。由于不是采用登录url, 用户名+密码的方式。配合工具使用,快速方便。
所谓用Cookie实现登录,就把过登录过的信息(包括用户名、密码以及其他的验证信息)打包一起发给服务器,告诉服务器我是登录验证过的。
不足之处,Cookie有过期时间,过一段时间再运行这个爬虫,需要重新获取一下Cookie的值。抓取数据过程是没有问题的。
关于Cookie的介绍:
-
Cookie分类
Cookie总是保存在用户客户端中,按在客户端中的存储位置,可分为内存Cookie和硬盘Cookie。Cookie的有效性,最短的浏览器关闭后就消失了,最长是可以一直保存,直到被删除。 -
Cookie用途
因为HTTP协议是无状态的,即服务器不知道用户上一次做了什么,这严重阻碍了交互式Web应用程序的实现。
在典型的应用是网上购物场景中,用户浏览了几个页面,买了一盒饼干和两饮料。最后结帐时,由于HTTP的无状态性,不通过额外的手段,服务器并不知道用户到底买了什么。
所以Cookie就是用来绕开HTTP的无状态性的“额外手段”之一。服务器可以设置或读取Cookies中包含信息,借此维护用户跟服务器中的状态。 -
Cookie的缺陷
1)Cookie会被附加在每个HTTP请求中,所以无形中增加了流量。
2) 由于在HTTP请求中的Cookie是明文传递的,所以安全性成问题。(除非用HTTPS)
3) Cookie的大小限制在4KB左右。对于复杂的存储需求来说是不够用的。
原文链接:http://www.jianshu.com/p/887af1ab4200