我们在使用模拟浏览器访问网站时,可能会遇到网站需要登录的情况,我的爬虫练习网站提供了这样一个登录练习案例[1]。如果你用浏览器手动测试,你会发现这样一个现象:第一次访问时,会自动跳转到登录页面。输入账号kingname和密码genius后,可以看到登录成功的页面,如下图:现在,你关闭浏览器再打开,再次访问这个网站,你会发现浏览器可以直接输入成功登录,登录页面将不再出现。我们都知道这是因为浏览器记住了网站的cookies。即使关闭浏览器再打开,cookies仍然存在,所以可以绕过登录功能。但如果您使用Selenium或Puppeteer/Pyppeteer,情况就不是这样了。首次登录成功后,退出程序。第二次重新运行程序时,爬虫需要重新登录。这个过程一是拖慢了爬虫的运行速度,二是网站很容易检测到你的账号异常——会不会是自动登录功能失效了?为什么别人的账号都正常,他的账号每隔一小时就要重新登录一次?可能是爬虫,发个验证码,一探究竟。同样的,有时候,登录网站的时候会出现一个很麻烦的验证码,但是一旦登录成功,这个验证码就再也不会出现了。处理这种验证码最简单的方法就是直接参与人工参与。那么如果爬虫每小时运行一次,那岂不是每小时都需要通过验证码?爬虫能不能只登录一次就再也不登录了?有两种方法。第一种方法也是大家能想到的最直观的方法:登录成功后,保存cookies。下次想再次登录时,直接在浏览器中设置这个cookie即可。网上有很多这种方法的例子。大家可以搜索关键字“seleniumgetscookies”和“seleniumsetscookies”,这里不再赘述。今天我们要说的是第二种方法,也是最简单的方法。而且这个方法听起来很弱智:如果我不关闭浏览器,它的Cookies不会被清除吗?但是仔细想想,按照你以前的经验,你的爬虫代码退出的时候,是浏览器吗?也自动关闭了?即使因为某种原因,爬虫代码本身崩溃了,浏览器也没有关闭,那么第二次启动爬虫时,如何重新连接到之前启动的浏览器呢?我们今天要做的就是把启动浏览器和启动爬虫这两个事情分开。先用一些方法单独启动浏览器,然后启动爬虫代码,让爬虫代码接管浏览器,控制浏览器。Chrome浏览器支持远程调试模式。开启此模式后,Puppeteer或Selenium可以通过websocket连接到它来控制它。首先,让我们启动Chrome的远程调试端口。您需要找到Chrome的安装位置。在Chrome的地址栏输入chrome://version,找到Chrome的安装路径,如下图:之后,我们需要执行命令启动支持远程调试功能的Chrome。如果您的计算机是Mac,则命令为:“/Applications/GoogleChrome.app/Contents/MacOS/GoogleChrome”--remote-debugging-port=9222--no-first-run--no-default-browser-check--user-data-dir=$(mktemp-d-t'chrome-remote_data_dir')注意,由于地址中有空格,所以可执行文件的路径一定要用引号括起来。如果你的电脑是Windows,那就很简单了。执行命令:filepath/chrome.exe--remote-debugging-port=9222启动后如下图:这时候不要碰chrome这个命令启动的。你先打开一个普通的浏览器,输入网址:http://127.0.0.1:9222/json/version,如下图:记住webSocketDebuggerUrl后面的地址。这是我们远程链接的地址。今天我们以Puppeteer为例,介绍如何连接到这个远程Chrome。在连接之前,我们先做一件事,在这个通过命令启动的Chrome中打开我们的登录练习页面,然后手动登录进去。如下图所示:然后,我们来写一段Puppeteer代码:constpuppeteer=require('puppeteer-core')asyncfunctionrun(){varaddress='ws://127.0.0.1:9222/devtools/browser/f6ede2a1-cf7b-4a0d-b0ea-9c0cd24d240d'constbrowser=awaitpuppeteer.connect({browserWSEndpoint:address,});constpage=awaitbrowser.newPage();response=awaitpage.goto('http://exercise.kingname.info/exercise_login_success',{waitUntil:'load',timeout:0});}run()这段代码的核心是两行,连接远程Chrome:varaddress='ws://127.0.0.1:9222/devtools/browser/f6ede2a1-cf7b-4a0d-b0ea-9c0cd24d240d'constbrowser=awaitpuppeteer.connect({browserWSEndpoint:address,});运行效果如下图所示:可以看到代码控制浏览器打开一个新的标签页,登录成功后可以立即打开页面,无需再次登录。你可以试一试,现在在终端窗口按Ctrl+C强制关闭当前爬虫代码,然后重新启动,你会发现还是登录后的页面。这样以后遇到需要登录的网站时,只需要使用这种远程调试方式,先启动一个支持远程调试的Chrome浏览器,然后在浏览器上手动完成登录操作,然后爬虫代码不再需要考虑登录这个动作,爬虫可以直接访问登录页面。在您自己的测试过程中,您可能会发现打开的选项卡越来越多。其实不用担心,这是因为我没有关闭当前选项卡来演示登录后的页面。当您的爬虫执行完操作后,您可以使用awaitpage.close()关闭当前选项卡。只要至少打开一个选项卡,浏览器窗口就可以永久使用。如果这篇文章的阅读量超过2000,我们就来说说如何使用Selenium调用具有远程调试功能的Chrome浏览器。参考资料[1]登录练习:http://exercise.kingname.info/exercise_login_success本文转载自微信公众号“未听密码”,可通过以下二维码关注。转载本文请联系Code公众号。