Security News
38% of CISOs Fear They’re Not Moving Fast Enough on AI
CISOs are racing to adopt AI for cybersecurity, but hurdles in budgets and governance may leave some falling behind in the fight against cyber threats.
@ljw1412/web-crawler-lite
Advanced tools
这是一个爬虫库。
顺便学习Typescript
、以及对项目架构的思考。
superagent
)# 使用 npm
npm install @ljw1412/web-crawler
# 使用 yarn
yarn add @ljw1412/web-crawler
const { Crawler, Page, logger } = require('@ljw1412/web-crawler')
// 默认并发数(concurrency)为1
const c = new Crawler({ concurrency: 5 })
// 设置默认回调事件
c.callback((err, { page, raw, $ }) => {
if (err) {
logger.error('错误', page.url, err)
} else if ($) {
// $ 采用 cheerio,一个专为服务端设计的实现jquery核心功能的包
logger.info('[title]', $('title').text())
}
})
// 添加需要爬取的页面
c.add(new Page({ type: 'html', url: 'https://jd.com' }))
// 以Page数组的形式添加
c.add([
new Page({ type: 'html', url: 'https://www.tmall.com' }),
new Page({ type: 'html', url: 'https://www.taobao.com' }),
])
// 也可以单独设置回调事件
c.add(
new Page({
type: 'html',
url: 'http://www.amazon.com',
// 更加细致的回调处理,优先级高于默认回调(此时不会走默认回调)。
callback: (err, { page, raw, $ }) => {
if (err) {
logger.error('错误', page.url, err)
} else if ($) {
// $ 采用 cheerio,一个专为服务端设计的实现jquery核心功能的包
logger.info('[Good Luck!]', $('title').text())
}
},
})
)
// 开始爬取
c.start()
除了使用callback
进行结果回调处理外你还可以使用on
/off
进行事件处理。
const { Crawler, Page, logger } = require('@ljw1412/web-crawler')
const c = new Crawler()
c.add([
new Page({ type: 'html', url: 'https://jd.com' }),
new Page({ type: 'html', url: 'https://www.tmall.com' }),
new Page({ type: 'html', tag: 'no-money', url: 'https://www.taobao.com' }),
])
// 监听所有的成功回调
c.on('data', ({ page, raw, $ }) => {
if ($) {
logger.success('[data]', $('title').text())
}
})
// 监听 page.type === 'html' 的成功回调
c.on('data.html', ({ page, raw, $ }) => {
if ($) {
logger.success('[data.html]', $('title').text())
}
})
// 监听 tag === 'no-money' 的成功回调
c.on('data#no-money', ({ page, raw, $ }) => {
if ($) {
logger.success('[data#no-money]', $('title').text())
}
})
// 监听所有的错误
c.on('error', (error) => {
logger.error('[error]', error)
})
c.on('end', () => {
logger.success('[end]')
})
c.on('log', (event) => {
logger.info('[日志]', event)
})
c.start()
const axios = require('axios')
const cheerio = require('cheerio')
const proxyAgent = require('proxy-agent')
const { Crawler, Page, logger } = require('@ljw1412/web-crawler')
const c = new Crawler()
async function axiosRequest(page, data) {
const {
id,
type,
url,
timeout,
headers,
proxy,
method,
data,
query,
emitter,
} = page
emitter.infoLog('Before Request', `#${id} axios:${url}`, { page })
const options = { timeout, headers }
if (['image', 'file'].includes(type)) options.responseType = 'arraybuffer'
if (proxy) {
// 请求代理处理
options.httpAgent = new proxyAgent(proxy)
options.httpsAgent = new proxyAgent(proxy)
emitter.warnLog('Request Proxy', `#${id} ${url} -> ${proxy}`, { page })
}
let resp
if (method === 'POST') {
resp = await axios.post(url, data, options)
} else {
resp = await axios.get(url, Object.assign(options, { params: query }))
}
cbData.raw = resp.data
switch (type) {
case 'html':
data.$ = cheerio.load(data.raw)
break
case 'json':
if (typeof cbData.raw === 'object') {
cbData.json = cbData.raw
break
}
try {
data.json = JSON.parse(data.raw)
} catch (err) {
emitter.errorLog(
'SyntaxError',
`#${id} ${url}\n$JSON解析错误: ${error.message}`,
{ error, page }
)
}
break
case 'image':
case 'file':
data.buffer = resp.data
break
}
}
// 覆盖默认请求方法
c.default.request = axiosRequest
c.add(
new Page({
type: 'html',
url: 'http://www.google.com',
proxy: 'socks5://127.0.0.1:1086',
})
)
c.callback((err, { page, raw, $ }) => {
if (err) {
logger.error('错误', page.url, err)
} else if ($) {
logger.info('[title]', $('title').text())
}
})
c.start()
const c = new Crawler({
concurrency: 5,
// 设置默认的请求头,所有被添加的Page都会使用。
headers: {
'User-Agent':
'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.138 Safari/537.36',
},
})
const page = new Page({
type: 'image',
url: 'XXX',
// 设置页面特有的请求头,将与默认请求头进行合并。
// 优先级高于默认请求头(即同名属性将覆盖默认请求头)。
headers: {
'User-Agent':
'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10; rv:33.0) Gecko/20100101 Firefox/33.0',
Referer: 'https://localhost',
},
})
// 为全局设置默认代理,向该爬虫队列添加页面时,如果未设置页面代理,那么页面会使用默认代理。
new Crawler({ proxy: 'socks5://127.0.0.1:1086' })
// 为单个页面设置代理,优先级高于全局默认代理。
// javascript 动态模式暂不支持代理请求。
new Page({
type: 'html',
url: 'https://www.google.com',
proxy: 'socks5://127.0.0.1:1086',
})
创建一个页面实例。
参数:
20 * 1000
。(err, data) => void
。html, image, file, json
或自定义字符串)。创建一个新的爬虫实例。
参数:
20 * 1000
。(err, data) => void
。()=>void
(page, done) => void
,最后使用执行回调done(err, data)
。puppeteer.launch([options])
中的options
。false
plugin
<(Crawler) => void>event
<string>listener
<Function>this
<Crawler>事件绑定/解绑,使用方法见监听绑定。
timeout
<number>this
<Crawler>设置超时时间,单位毫秒(ms)。但是优先级低于Page
实例中的timeout
。
可以在运行时进行修改,对后面添加的页面有效。
callback
(err, data) => voidthis
<Crawler>设置回调方法,格式同构造函数传参的options.callback
。但是优先级低于Page
实例中的callback
。
可以在运行时进行修改,对后面添加的页面有效。
filter
(page: Page) => booleanthis
<Crawler>设置过滤方法。返回值为 false 将不会加入爬虫队列。可以在运行时进行修改,对后面添加的页面有效。
this
<Crawler>this
<Crawler>向队列中添加请求一个或多个页面(Page
)。
this
<Crawler>this
<Crawler>向队列中添加请求一个或多个页面。这里传的是 Page 构造器的参数而不是 Page 实例。
开始爬取。
暂停爬取。
停止爬取。
停止爬取并返回结束事件。
FAQs
基于Node.js的网络爬虫(轻量版),该版本不支持动态页面爬取。
We found that @ljw1412/web-crawler-lite demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 0 open source maintainers collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
CISOs are racing to adopt AI for cybersecurity, but hurdles in budgets and governance may leave some falling behind in the fight against cyber threats.
Research
Security News
Socket researchers uncovered a backdoored typosquat of BoltDB in the Go ecosystem, exploiting Go Module Proxy caching to persist undetected for years.
Security News
Company News
Socket is joining TC54 to help develop standards for software supply chain security, contributing to the evolution of SBOMs, CycloneDX, and Package URL specifications.