上一节爬取了知乎美女精华话题下的子问题,并不需要登陆,直接抓取页面就可以了。但有些页面需要登陆后才可见。
比如 https://www.zhihu.com/topic
登陆状态下是
非登陆状态,
当提到登陆,必须对Http协议有一些了解,推荐《图解Http》。
通俗的说,HTTP 是一种无状态的协议, 协议本身不保留之前的一切请求信息和响应信息,也就是说,对于一个刚刚发送了 HTTP 请求的客户端再次发起请求时,服务端并不知道之前访问过。假设要求登陆认证的Web页面本身无法进行状态的管理(不记录已登录状态),那么每次跳转新页面不是要再次登陆,就是要在每次请求报文中附加参数来管理登陆状态。于是引入Cookie技术。Cookie技术通过在请求和响应报文中写入Cookie信息来控制客户端的状态
1. 浏览器第一次发起 HTTP 请求时,没有携带任何 Cookie 信息,服务器收到请求并返回给浏览器的HTTP响应,同时
HTTP 响应包括了一个响应头 Set-Cookie 字段,它的值是要设置的 Cookie。
2. 浏览器收到来自服务器的 HTTP 响应,响应头中发现有 Set-Cookie 字段,就会将该字段的值保存在内存或者硬盘中。
3. 浏览器下次给该服务器发送 HTTP 请求时, 会将 Cookie 信息附加在 HTTP 请求的头字段 Cookie 中。
4. 服务器收到这个HTTP请求,发现请求头中有Cookie字段, 便知道之前就和这个用户打过交道了。
如何实现模拟登陆呢
首先进入知乎登陆界面https://www.zhihu.com/#signin,F12打开开发者工具,Network栏,我们试着错误的输入一个账号密码
在左下角找到email
从浏览器的请求可以发现几个关键的信息
1.登陆的URL为https://www.zhihu.com/login/email
2.登录需要提供的表单数据有5个:用户名(email)、密码(password)、验证码(captcha)、验证码的类型(captcha_type)、_xsrf。
3. 获取验证码的URL地址是https://www.zhihu.com/captcha.gif?r=1495682872878&type=login&lang=cn
xsrf是一串伪随机
数,它是用于防止跨站请求伪造的。它一般存在网页的 form 表单标签中,为了证实这一点,可以在页面上搜索 “xsrf”,果
然,从下图可以看到 _xsrf在一个隐藏的 input 标签中
对https://www.zhihu.com/#signin发起登陆请求
下载登陆页面,再从源代码中抽取
获取xsrf
public String get_xsrf(){
String page = getHtmlPage("https://www.zhihu.com");
Document doc = Jsoup.parse(page);
Elements srfs = doc.getElementsByAttributeValue("name", "_xsrf");
String xsrf = srfs.first().attr("value");
return xsrf;
}
中文验证码暂时解决不了,但实验多次后发现有手动输入的字符验证码。
这样的验证码少了一个参数captcha_type
所以只需要将验证码图片下载到本地在对应的设置参数就行了。首先是下载验证码图片,通过对页面源代码的分析并没有找到图片,那就应该是通过js传过来的
图片中的r是个随机数,只需要像_xsrf一样请求相应的地址就行了,下载图片,从控制台输入的方式设置验证码参数。即在首次登录是下载验证码到本地之后人工查看验证码之后控制台输入验证码设置到请求参数中
留坑,待更新。。。。。