• python模拟登陆知乎


    ---恢复内容开始---

    在完成前面的阶段的任务之后,我们现在已经能够尝试着去模拟登录一些网站了。在这里我们模拟登录一下知乎做一下实验。笔者在这里总共用了三天多的时间,下面给大家分享一下笔者是怎么一步一步的模拟登录成功的。也希望大家能够吸取我的教训。
    初步的模拟登录
    下面这段代码是笔者最初写的,我们慢慢来看
    import requests
    from bs4 import BeautifulSoup as bs
    ssesion = requests.session()
    headers = {
       'Connection': 'keep-alive',
       'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8',
       'Accept-Language': 'en-US,en;q=0.8,zh-Hans-CN;q=0.5,zh-Hans;q=0.3',
       'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/45.0.2454.101 Safari/537.36',
       'Accept-Encoding': 'gzip, deflate, sdch',
       'Host': 'www.zhihu.com',
    }

    login_data = {'username': '', # 替换为账号
                 'password': '', # 替换为密码
                 'remember_me': 'true',
                 'Referer': 'https://www.baidu.com/',
                  }

    response = bs(requests.get('http://www.zhihu.com/#signin').content, 'html.parser')
    xsrf = response.find('input',attrs={'name':'_xsrf'})['value']
    login_data['_xsrf'] =xsrf
    responed = ssesion.post('http://www.zhihu.com/login/email',headers=headers,data=login_data)
    print(responed)
    在最初的写模拟登录知乎的时候,笔者也是通过抓包,发现了,cookie中有一个_xsrf的属性,类似于token的作用。而这个东西的存在,就让我们在模拟登录的时候,必须将这个属性作为参数一起加在请求中发送出去,那么怎么获得这个东西呢?似乎又是一个问题。
    我想到的方法,就是随便访问一个页面,然后再页面元素中去定位到_xsrf这个字段,然后抓取下来,添加到data里,在请求的时候一起发出去就可以了。
    然后为什么会去用ssesion去请求,因为在知乎上,它的xsrf是一直在变化的,我们每一次请求,它都在变。所以如果我们用requests去请求的话,就无法登录成功。
    那么上面这段代码基本已经符合我们的要求了。我们运行看一下结果
    Traceback (most recent call last):
      File "C:/Users/Administrator/PycharmProjects/Practice/Login_zhihu.py", line 20, in <module>
        xsrf = response.find('input',attrs={'name':'_xsrf'})['value']
    TypeError: 'NoneType' object is not subscriptable
      
    报错了,获取到的xsrf是空的,怎么办呢?嗯,根据这里的报错信息显示应该是类型错误,那就是获取xsrf那一段有错,我们单独把那一段代码拿出去运行看看结果。
    定位并修复报错信息
    既然知道了错误原因我们就去看看,到底是哪儿错了,要怎么解决。
    首先,我单独的把获取xsrf那一段代码拿出来运行
    import requests
    from bs4 import BeautifulSoup as bs

    response = bs(requests.get('http://www.zhihu.com/#signin').content, 'html.parser')
    print(response)
    xsrf = response.find('input',attrs={'name':'_xsrf'})['value']
    print(xsrf)
    在这里,分开进行打印,以便查看到底是走到哪一步出的错。
    运行这一段代码得到结果如下显示:
    Traceback (most recent call last):
      File "C:/Users/Administrator/PycharmProjects/Practice/Login_zhihu.py", line 6, in <module>
        xsrf = response.find('input',attrs={'name':'_xsrf'})['value']
    TypeError: 'NoneType' object is not subscriptable
    <html><body><h1>500 Server Error</h1>
    An internal server error occured.
    </body></html>
    在这里报了500,也就是说我们在get请求的那里就已经出错了,然后下方的xsrf也没有获取到。在这里我首先想到的是先解决爬取的xsrf为空的问题,这里实际上走入了一个误区。之所以会爬取xsrf失败,实际上是由于在请求的时候就失败了,导致根本获取不到xsrf。所以应该是解决500的问题先。
    那么怎么解决500问题呢?
    经过前辈的教导,我在请求后面加上了headers,再次运行
    import requests
    frombs4importBeautifulSoupasbs
    headers = {
    'Connection':'keep-alive',
    'Accept':'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8',
    'Accept-Language':'en-US,en;q=0.8,zh-Hans-CN;q=0.5,zh-Hans;q=0.3',
    'User-Agent':'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/45.0.2454.101 Safari/537.36',
    'Accept-Encoding':'gzip, deflate, sdch',
    'Host':'www.zhihu.com',
    }

    login_data = {'username':'',# 替换为账号
    'password':'',# 替换为密码
    'remember_me':'true',
    'Referer':'https://www.baidu.com/',
    }

    response = bs(requests.get('http://www.zhihu.com/#signin',headers=headers).content,'html.parser')
    xsrf = response.find('input',attrs={'name':'_xsrf'})['value']
    print(xsrf)
    好的,在运行看看:
    899ce2556d7e705ca9bbf2b818a48d40
          
    好的,这里我们可以看到是成功的爬取到了xsrf的信息,那么我们将这段代码在拿到之前的模拟登录的代码中去看看。
    成功模拟登录知乎       
    import requests
    from bs4 import BeautifulSoup as bs
    ssesion = requests.session()
    headers = {
       'Connection': 'keep-alive',
       'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8',
       'Accept-Language': 'en-US,en;q=0.8,zh-Hans-CN;q=0.5,zh-Hans;q=0.3',
       'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/45.0.2454.101 Safari/537.36',
       'Accept-Encoding': 'gzip, deflate, sdch',
       'Host': 'www.zhihu.com',
    }

    login_data = {'username': '', # 替换为账号
                 'password': '', # 替换为密码
                 'remember_me': 'true',
                 'Referer': 'https://www.baidu.com/',
                  }

    response = bs(requests.get('http://www.zhihu.com/#signin',headers=headers).content, 'html.parser')
    xsrf = response.find('input',attrs={'name':'_xsrf'})['value']
    login_data['_xsrf'] =xsrf
    responed = ssesion.post('http://www.zhihu.com/login/email',headers=headers,data=login_data)
    print(responed)
    运行这段代码得到的结果是
            <Response [200]>
     
    返回状态为200,说明我们已经模拟登录成功了。经历过蛮多挫折哈,光是错误定位那一块儿,我就折腾了整整一个晚上,还请教了好几个程序员都没有搞定。这里提醒大家一下,可千万不要犯我这样的错误咯。在做爬虫的时候,一定要记得请求的时候加上头信息。

    ---恢复内容结束---

  • 相关阅读:
    Java 编译器
    ElasticSearch 集群搭建
    致:奋斗路上的自己
    ElasticSearch 简单入门
    char* 和 char* const
    usb虚拟网卡与串口
    usb虚拟网卡与串口
    ethtool处理网卡不断重启
    客车网上订票系统项目--票务管理、前端个人信息修改
    mysql错误号码2003 can't connect to mysql server on 'localhost' (0)解决方案
  • 原文地址:https://www.cnblogs.com/rookie-c/p/5753394.html
Copyright © 2020-2023  润新知