请稍等 ...
×

采纳答案成功!

向帮助你的同学说点啥吧!感谢那些助人为乐的人

Selenium模拟登录知乎的问题

知乎更新了接口,现在不能够直接输入用户名、密码然后点击登录按钮弹出验证码了,具体的我看了下慕课其他同学的问题和老师的回答,参考使用selenium接管Chrome浏览器,百度了以下,找到两种方法,一种是使用代理,也就是mitmproxy,安装这个第三方库,然后设置本机代理ip地址,开启8001端口,让流量都走这个端口,然后进入mitmproxy状态编写干扰脚本,重新用命令行启动mitmproxy干扰脚本 监听8001端口的请求与响应,启动webdriver 顺利获得cookies。(参考来源:selenium爬虫被检测到 该如何破?)第二种是通过Google Chrome的Console中输入window.navigator.webdriver就可以查看非selenium环境下其值为undefined,而在selenium环境下,其值为true,如下所示:
Google Chrome Console
反正还有一些JS预定义的变量可以检测出来是不是在用selenium,可以被检测出来,知道其原理后就可以通过mitmproxy类型代理工具,修改js文件,替换文件内所有变量关键词,或者将其不可执行,从而避免被识别。
和上面相同,还有一种就是配置Google Chrome可执行程序到系统环境变量,然后添加启动参数,使其在运行时不被检测出是webdriver。

我无意中摸索出来一个可以模拟出点击登录,虽然不能成功,但是可以弹出验证码的方法,也就是在密码输入框后添加一个KEY.ENTER,模拟按键回车键,然后再模拟点击登录按钮,就行了。然后进入Console可以看到被拒绝的信息:

{ "error": { "code": 10001, "message": "10001:\u8bf7\u6c42\u53c2\u6570\u5f02\u5e38\uff0c\u8bf7\u5347\u7ea7\u5ba2\u6237\u7aef\u540e\u91cd\u8bd5" } }

通过Google Chrome的Console输入:

alert("\u8bf7\u6c42\u53c2\u6570\u5f02\u5e38\uff0c\u8bf7\u5347\u7ea7\u5ba2\u6237\u7aef\u540e\u91cd\u8bd5")

即可解析出来消息的内容:
图片描述
原因你懂的,被检测出来是selenium环境,具体怎么解决还不知道,希望老师指点一下。

正在回答 回答被采纳积分+3

1回答

提问者 Icarus1264 2019-05-07 10:17:50

老师,我已经找到解决方案,知道怎么通过最新版的Selenium来模拟登录知乎了,并可以获取cookie。

首先,前面先配置一个ChromeOptions(),并再其中添加如下配置:

from selenium.webdriver import Chrome
from selenium.webdriver import ChromeOptions

option = ChromeOptions()
option.add_experimental_option('excludeSwitches', ['enable-automation'])
driver = Chrome(executable_path=".../.../chromedriver.exe",options=option)

即开启了Google Chrome的开发者模式,默认的js都会变成和真的浏览器登录一样,然后就是继续模拟输入用户名、密码和点击登录按钮,但是不知道是知乎还是Chrome有Bug,点击按钮总是失败,所以我多加上了一个模拟点击回车按钮的操作,就可以正常模拟登录知乎,接下来就可以获取cookie了。示例代码如下,仅供参考:

参考来自:一行 js 代码识别 Selenium+Webdriver 及其应对方案

# -*- coding: utf-8 -*-
import time
import scrapy
from selenium.webdriver import Chrome, ChromeOptions
from selenium.webdriver.common.keys import Keys


class ZhihuSpider(scrapy.Spider):
    name = 'zhihu'
    allowed_domains = ['www.zhihu.com']
    start_urls = ['https://www.zhihu.com/']

    def start_requests(self):
        """
        scrapy中所有的spider都是从start_requests方法开始
        它会遍历所有的start_urls,并生成返回每一个Request请求
        我们只需要重写这个方法,每次都模拟登录知乎。
        :return:
        """

        # 构建一个模拟谷歌浏览器的配置文件
        options = ChromeOptions()

        # 添加开发者模式配置信息到配置文件
        options.add_experimental_option('excludeSwitches', ['enable-automation'])

        # 构建一个用于模拟浏览器操作的浏览器browser,并设置其所在的执行路径
        browser = Chrome(executable_path="C:/Users/Icarus/ArticleSpider/drivers/chromedriver.exe", options=options)

        # 模拟浏览器请求知乎登录页面
        browser.get("https://www.zhihu.com/signin")

        # 定位知乎登录页面中的用户名输入框,并模拟输入用户名
        browser.find_element_by_css_selector(".SignFlow-accountInput input[class='Input']").send_keys("13873288573")

        # 定位知乎登录页面中的密码输入框,并模拟输入密码
        browser.find_element_by_css_selector(
            ".SignFlow-password .SignFlowInput .Input-wrapper input[class='Input']").send_keys("qaz1584279" + Keys.ENTER)

        # 定位知乎登录页面中的登录按钮,并模拟点击登录按钮
        browser.find_element_by_css_selector(".Button.SignFlow-submitButton.Button--primary.Button--blue").click()

        # 暂停一下,观察结果
        time.sleep(60)


0 回复 有任何疑惑可以回复我~
  • bobby #1
    确实js可以检测出自动启动的chrome浏览器,但是课程中已经讲解了另一种更简单的方法就是自己启动chrome浏览器,然后将selenium连接到这个真正的chrome中,你可以继续看课程的视频,有讲解这个内容的
    回复 有任何疑惑可以回复我~ 2019-05-08 14:59:04
问题已解决,确定采纳
还有疑问,暂不采纳
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号