工作日志6 Nodejs和puppeteer学习
这个项目本身使用Aurora Vision提供的api进行爬虫,但Aurora Vision更新了他们的api版本,并且需要申请额外服务,因此该项目只能从网页基于puppeteer进行爬虫。
puppeteer是一个很容易上手的爬虫库,基本看quick start就能理解其是如何模拟人的一些操作来爬虫的。该项目的难点在于我不会java,也不会js,熟悉这些花费了很久的时间。
node.js和puppeteer安装
先装npm,后装puppeteer,挺简单的
node.js的调试
console.log('this is test')
控制台输出
console.time('puppeteer')
console.timeLog('puppeteer')
console.timeEnd('puppeteer') 计算时间
node inspect xxx.js
: 内置的检查器
cont, c: 继续执行
next, n: 下一步
step, s: 进入
out, o: 走出去
pause:暂停运行代码(如开发者工具中的暂停按钮)
在vs中设置js的debug环境vs nodejs
youtube视频教程Getting started with Node.js debugging in VS Code
在vs中debug:在控制台输入noed xxx.js之后即可打开debug页面。 vs inline value: Open Settings Search for “debug” Navigate to Features > Debug Change the setting for Debug: Inline Values
另外还可以使用devtool等方法。我觉得还是vs最方便。
node.js的一些迷惑语法
module exports: 模块化。
很多时候一个文件会被包装成一整个模块,直接对其debug是不会有反映的。要在别的test文件中导入,再逐行debug。 例如 #./scraper.js module.exports = {}
#./test.js
const test = require('./scraper')
data = test.execute()
console.log(data)
return多个值
return[1,2,3,4]
删除某个元素
#从末尾删除一个元素
array.pop()
#从开头删除一个元素
array.shift()
#从某位置删除几个
array.splice(0,2)
#使用filter
filter() 有一个参数,一个回调方法。当 filter 方法遍历数组元素时触发回调。它会将三个值传递给回调:当前值或元素、当前数组索引和完整数组。
var array = [1, 2, 3, 4, 5, 6, 7, 8, 9, 0];
var filtered = array.filter(function(value, index, arr){
return value > 5;
});
判断数组是否为空
没有直接的isnull这种用法。可以用!array.length判断
一些js表达式
参考这个可以直接运行的网站mozilla-js
puppeteer的调试
设置headless以及devtools,在浏览器中执行调试。
const browser = await puppeteer.launch({
args: ['--no-sandbox', '--disable-setuid-sandbox'],
headless:false,
devtools: true,
ignoreHTTPSErrors: true
});
puppeteer的一些语法
官方文档page
获取元素page.$() page.$$()
首先,page上的所有可执行元素称作element node,只能对其进行操作。
使用page.$()
以及page.$$()
选择所需要的元素。
selector有很多种类
根据type const n = await page.$(“h4”)
根据name const f = await page.$(’[name=“search”]')
根据class name const f = await page.$(".heading")
根据id const f = await page.$("#id")
根据arrtibute(tag name and attribute name) const n = await page.$(“li[class=‘heading’]”)
另一种是根据Xpath,使用page.$x()
,xpath可以直接在devtool中获得。
注意:有的页面加载很慢,需要先确保页面元素存在再进行选择。
page.waitForTimeout(10000)
单位为ms。为了反反爬虫,最好设置的大一些。
innerText
一般先获取td列表,对于每一个获取td.innerText const data = await page.$$eval(’table tr td’, tds => tds.map((td) => { return td.innerText; }));
page.type
大致是输入的意思,把value输入某个可选择对象
page.click
这里有个牛逼的操作 await page.click(’[name=“comboBoxInput”]’,{ clickCount: 3 }); await page.type(’[name=“comboBoxInput”]’, plant_name); 模拟点击三次文本框,接着使用type,可以直接输入所需要的值。
评估函数
使用page.evaluate()
获取内部的函数值。
常常与=>这个js中的lambda表达式联合使用。
例如
const plantNames = await page.evaluate(() => {
const tds = Array.from(document.querySelectorAll(’.app-tree-clickable ‘)).map(td => td.innerText);
return tds.filter(function(value,index) { return value.length < 17; })
})
map和filter
我的理解: map(x => x.function) <==> apply(lambda x:func(x)) filter(x => {return limit_function(x)}) <==> apply(lambda x:func(x))
Array from
获取数组(列表)
转置矩阵
虽然没看懂 const arrayT = await array[0].map((_, colIndex) => array.map(row => row[colIndex]))