Scrapy基础(十四)————知乎模拟登陆

#-*-coding:utf-8 -*-
__author__ = "ruoniao"
__date__ = "2017/5/31 20:59"

之前我们通过爬取伯乐在线的文章,伯乐在线对爬取没有什么限制,这次爬取知乎,就有了爬取限制,首先就是
登录限制;为破解限制,首先就是模拟登录

模拟登陆首先要明白的就是session和cookie机制:

简单的说(个人理解):
  http是一种无状态的协议,为解决用户每次都需要输入密码登录的烦恼,也为了服务器能够记住每次请求的浏览器,就有了会话机制,

就是每次对话不需要问你是谁,浏览器只需要将服务器原先发送给浏览器的ID原封不动的还给服务器,这样服务器就可以在自己的
数据库中查找这个ID就可以,而只有这个ID是没用的,若想要用户登录,还需要用用户名和密码,加密后以cookie的形式存储在本地,

下次请求直接发送给服务器就行

总之:为了服务器和浏览器之间互相确认身份,服务器生成一个session_id并且保存在服务器,还有给浏览器一份,浏览器将这个session_id写入cookie,

发送给服务器,服务器对照自己保存在本地的,就能互相确认身份;不同的是:cookie中还带了用户的个人信息等

    
        cookie是存储在本地的记录某个网站的个人信息的机制
        session是存储在服务器中的记录某个浏览器(用户)的信息的机制,更安全;
具体理解可参考这篇文章

不同的网站模拟登录的策略不同,不同的网站要进行不同的分析;但都是大同小异;做过web的明白,无非就是用户的验证;较难的就是识别验证码了

知乎的登录破解:

1:这里遇到了坑,因为在firebug中测试时,post到url时没有填写验证码;而通过requests post到URL
   具体参数时报错:验证码错误,这就很纳闷了;
    2:原来:当向首页get时,因为有cookies,所以登录时就不需要填写验证码;通过代码时没有加cookies,需要填写验证码
    而验证码不好识别,只能更换思路
    3: 模拟浏览器的行为,若当初为取的xsrf时get带上cookie,下次登录就不需要验证码了
    4:那么怎么才能将cookie post到URL呢?了解requests.post()方法的知道:post()可带的参数很多
    其中cookies= {}或CookieJar
    5:将cookies以字典的形式post方便操作,只需要在firebug中的cookies复制为字典的格式
       以CookieJar的形式:因为cookie是保存在硬盘的,可以参考这篇博文

6:因为cookie是有生存周期的额,为了下面重新登录,可以将登录后的cookie以txt的形式保存在本地,下次直接load就可以

实例代码注释

  1 import requests
  2 #适合python2和python3版本的导包
  3 try:
  4     import cookielib
  5 except:
  6     import http.cookiejar as cookielib
  7 import re
  8 from urllib import parse, request
  9
 10 #使用会话机制向url发送request,提高效率,不必每次都发请求(类比浏览器直接在本标签页操作,不需重新产生新的标签页)
 11 session = requests.session()
 12 #将会话产生的cookies保存在本地
 13 session.cookies = cookielib.LWPCookieJar(filename="cookies.txt")
 14
 15 #浏览器版本信息,目的是伪装成一个浏览器,让服务器认为我们的代码是一个浏览器请求而不是爬虫,避免被拒绝
 16 headers = {
 17     "User-Agent":"Mozilla/5.0 (Windows NT 10.0; WOW64; rv:53.0) Gecko/20100101 Firefox/53.0",
 18     "Host":"www.zhihu.com",
 19     "Referer":"https://www.zhihu.com/",
 20 }
 21
 22 #获取登录xsrf
 23 def get_xsrf():
 24
 25     url = "https://www.zhihu.com/#signin"
 26
 27     try:
 28         #带上cookie,避免产生验证码识别
 29         req = session.get(url=url,cookies=cookies,headers=headers)
 30         #通过正则表达式解析出 xsrf 类比csrf机制
 31         xsrf = re.findall(‘<input type="hidden" name="_xsrf" value="(.*?)"/>‘,req.text)
 32         if xsrf:
 33             xsrf = xsrf[0]
 34             print(xsrf)
 35             return xsrf
 36         else:
 37             return xsrf
 38     except Exception as e:
 39         print(e)
 40         print("failed download")
 41
 42
 43
 44 #知乎登录
 45 def zhihu_login(account,password):
 46
 47     #首先获取xsrf
 48     xsrf = get_xsrf()
 49     #判断是手机号:以手机号登录,提交表单和提交URL不同,构造不同的URL和表单
 50     if re.match("\d{10}",account):
 51
 52         url = "https://www.zhihu.com/login/phone_num"
 53         data={
 54             "_xsrf":xsrf,
 55             ‘remember_me‘: ‘true‘,
 56             "password":password,
 57             "phone_num":account
 58         }
 59     if ‘@‘ in account:
 60         url = "https://www.zhihu.com/login/email"
 61         data={
 62             "_xsrf":xsrf,
 63             ‘remember_me‘: ‘true‘,
 64             "password":password,
 65             "email":account
 66         }
 67     #将获取到的xsrf加载到cookie中
 68     cookies["_xsrf"] = xsrf
 69     #带上表单,头信息,cookies申请登录
 70     r = session.post(url=url,data=data,headers=headers,cookies=cookies)
 71     print(r.text)
 72     #登录成功将cookies保存到本地
 73     session.cookies.save()
 74
 75
 76 #获取首页;登录后可直接获取,因为session中已经(带了)加载了cookie
 77 def get_index():
 78     response = session.get("https://www.zhihu.com/",headers=headers)
 79     print(response.status_code)
 80     #将首页写入本地文件
 81     with open("index_page.html","wb") as f:
 82         f.write(response.text.encode("utf-8"))
 83     print("write ok")
 84
 85 #查看登录状态;向一个只有登录的页面get,若登录会返回200;否则304,会重定向到登录页(重定向后会返回200)
 86 def is_login():
 87     url = "https://www.zhihu.com/inbox"
 88     #allow_redirects  禁止重定向
 89     response  = session.get(url=url,headers=headers,allow_redirects=False)
 90     #判断是否登录
 91     if response.status_code != 200:
 92         return False
 93     else:
 94         return True
 95
 96
 97 #先尝试本地cookie登录,不成功使用浏览器copy下来的cookies重新登录,生成本地cookies
 98 try:
 99     #先尝试加载之前保存在本地的cookies
100     session.cookies.load(ignore_discard=True)
101     print("cookies 已记载")
102 except:
103     #没加载就重新登录
104     print("cookie 未加载")
105     #这个cookie是从firebug中复制来的
106     cookies = {
107     "d_c0":"",
108     "l_cap_id":"",
109     "r_cap_id":"",
110     "cap_id":"",
111     "_zap":"",
112     "__utmc":"",
113     "__utmb":"",
114     "__utmv":"",
115     "__utma":"",
116     "__utmz":"",
117     "q_c1":""118
119 }
120     #调用登录函数,成功后会更新cookie到本地
121     zhihu_login("[email protected]","19971013zf")
122     #更新成功后重新加载cookies
123     session.cookies.load(ignore_discard=True)
124
125
126 print(is_login())
时间: 2024-11-10 09:00:09

Scrapy基础(十四)————知乎模拟登陆的相关文章

Scrapy基础(十四)————Scrapy实现知乎模拟登陆

模拟登陆大体思路见此博文,本篇文章只是将登陆在scrapy中实现而已 之前介绍过通过requests的session 会话模拟登陆:必须是session,涉及到验证码和xsrf的写入cookie验证的问题:在scrapy中不需担心此问题,因为Request会保证这是一个会话,并且自动传递cookies原理想通,因为验证码识别的问题,这里先使用cookie模拟登陆 1 # -*- coding: utf-8 -*- 2 3 import scrapy 4 import json 5 import

Bootstrap&lt;基础十四&gt; 按钮下拉菜单

使用 Bootstrap class 向按钮添加下拉菜单.如需向按钮添加下拉菜单,只需要简单地在在一个 .btn-group 中放置按钮和下拉菜单即可.也可以使用 <span class="caret"></span> 来指示按钮作为下拉菜单. 下面的实例演示了一个基本的简单的按钮下拉菜单: <!DOCTYPE html> <html> <head> <title>Bootstrap 实例 - 基本的按钮下拉菜单&

第二十九节: 模拟登陆

一.126,163邮箱模拟登陆 1 # -*- coding:utf-8 -*- 2 import time 3 from selenium import webdriver 4 def login126_or_163emall(url): 5 login_name = input("请输入账号:") 6 login_password = input("请输入密码:") 7 8 # 打开自动测试软件Chrome 9 driver = webdriver.Chrome

Python 基础 - Day 1 Assignment - Login 模拟登陆

作业要求: 1. 用户输入帐号密码进行登陆 2. 用户信息保存在文件内 3. 用户密码输入错误三次后锁定用户 SAMPLE 1: By 刘 步骤: 1. 字符串读取转成字典 user_info = 'Eric:123456#Catherine:098765' user_list = user_info.split('#') print(user_list) user_dic ={} # 创建空字典 for item in user_list: item_list = item.split(':'

Scrapy基础(十二)————异步导出Item数据到Mysql中

异步导出数据到Mysql中 上次说过从Item中同步写入数据库,因为网络的下载速度和数据库的I/O速度是不一样的所以有可能会发生下载快,但是写入数据库速度慢,造成线程的堵塞:关于堵塞和非堵塞,同步和异步的关系,因为没接触过,所以也不是很好的理解,这里查看了些资料,已做记录 链接1:https://www.zhihu.com/question/19732473;http://wiki.jikexueyuan.com/project/twisted-intro/ 实现异步写入mysql数据库的思路:

linux基础十四

1.tune2fs -l /dev/DEVICE     -l:查看超级块中的信息     -L lable:设定卷标     -m:预留管理员的空间     -j:如果原来的文件系统的为ext2,-j能够将其提升为ext3     -o:设定默认挂载选项     -O:调整分区特性           2.fsck 修复文件系统错误     -t: tstype     -a:自动修复错误     -r:交互式修复错误      3.修改交换分区     mkswap /dev/DEVICE

Java基础十四

1 对象数组 示例: package com.xuweiwei; /** * 学生类 */ public class Student { private String name; private Integer age; public Student() { } public Student(String name, Integer age) { this.name = name; this.age = age; } public String getName() { return name;

Python模拟登陆万能法-微博|知乎

Python模拟登陆让不少人伤透脑筋,今天奉上一种万能登陆方法.你无须精通HTML,甚至也无须精通Python,但却能让你成功的进行模拟登陆.本文讲的是登陆所有网站的一种方法,并不局限于微博与知乎,仅用其作为例子来讲解. 用到的库有"selenium"和"requests".通过selenium进行模拟登陆,然后将Cookies传入requests,最终用requests进行网站的抓取.优点就是不但规避了"selenium"其本身抓取速度慢的问题

Bootstrap&lt;基础二十四&gt; 缩略图

Bootstrap 缩略图.大多数站点都需要在网格中布局图像.视频.文本等.Bootstrap 通过缩略图为此提供了一种简便的方式.使用 Bootstrap 创建缩略图的步骤如下: 在图像周围添加带有 class .thumbnail 的 <a> 标签. 这会添加四个像素的内边距(padding)和一个灰色的边框. 当鼠标悬停在图像上时,会动画显示出图像的轮廓. 下面的实例演示了默认的缩略图: <!DOCTYPE html> <html> <head> &l