当前位置: 首页 > 后端技术 > Python

在puppeteer和request之间传递cookie

时间:2023-03-25 23:12:11 Python

参考QQ群-Javascript高级爬虫-作者自建群,欢迎加入!awesome-java-crawler-作者收集的与爬虫相关的工具和资料。Puppeteer中文文档request.js库前言目的是用puppeteer实现登录过程的自动化,将登录后获取的合法cookie传输到node端,实际抓取大量数据使用request提高爬取性能和可靠性.puppeteer->request首先,将jar属性添加到请求的默认参数中:constcookieJar=request.jar()constrp=request.defaults({jar:cookieJar,...//其他请求的默认参数})这样,使用这个rp对象就会使用这个cookieJar对象来存储从response中解析出来的cookies。您还可以通过操作cookieJar对象来添加、删除、修改和检查单个cookie。通过puppeteer从浏览器获取cookiesconstcookies=awaitpage.cookies()这里的cookies是普通的javascript对象数组,每个元素包含name、value、domain、path、expires、httpOnly、secure等属性,填入将浏览器获取的cookie放入cookieJar中。这一步值得强调的是:cookieJar中的每一个cookie都是一个cookie对象,不是简单的js对象,cookieJar.setCookie不接受简单的js对象,要么创建一个Cookie对象,要么传入一个字符串让这个方法自己解析,我这里选择第一个选项,所以我们必须引入request-dependentcookieprocessing依赖tough-cookie库,所以需要显式安装和导入这个库,注意不要使用最新版本,否则会和tough-cookie不一致请求中的依赖版本;您需要从package-lock.json中找到tough-cookie的版本号,然后使用npminstalltough-cookie@x.x.x安装特定版本。另外还有两个地方需要注意:tough-cookie的cookie对象使用key而不是name作为cookie名称;cookie对象的expires属性是一个Date对象或者'Infinity'字符串,puppeteer端对象中的expires是一个unix时间戳,用-1是永久的;因此,需要进行以下转换:cookies.forEach(json=>{const{name,domain}=jsonjson.key=namejson.expires=json.expires>0?newDate(json.expires*1000):'Infinity'constcookie=Cookie.fromJSON(json)cookieJar.setCookie(cookie,'https://'+domain)})完成cookie的设置后,nodejs端就是相当于在登录后状态,可以正常请求登录后权限内容请求->puppeteer有时需要将cookie从nodejs端反向传输到浏览器端,比如使用浏览器完成一些复杂的操作。这里涉及到上一节的逆运算这里麻烦的是request封装后的cookie操作方法不全面。比如我发现无法使用cookieJar.getCookies()方法获取'.'域下的cookies。下面的方法用于一次性获取cookieJar中的所有cookie对象asyncfunctionallCookies(jar){conststore=jar._jar.storereturn(awaitPromise.all(Object.keys(store.idx).map(d=>util.promisify(store.findCookies).call(store,d,null)))).flat()}注意:上面像'_jar'这样的属性属于tough-cookie的内部私有属性,也就是说上面的代码其实是一种hack方法,可能不适用于其他版本。util.promisify是nodejs标准库中的一个方法,用于将回调方法的函数转换为Promise方法Array。flat方法只在node11有,如果你用的是旧版本,请自己写方法展开数组,然后简单的把Cookie对象转换成puppeteer接受的普通js对象constcookies=awaitallCookies(cookieJar)cookies=cookies.map(c=>({...c,expires:c.expiresinstanceofDate?c.expires.getTime()/1000:-1,name:c.key}))awaitpage.setCookie.apply(page,cookies)因为Page.setCookie接受的是变长参数而不是数组,所以使用apply调用