爬虫抓取网页数据(WebSpiderWebSpider2021/05/23更新演示)

优采云 发布时间: 2022-01-14 22:03

  爬虫抓取网页数据(WebSpiderWebSpider2021/05/23更新演示)

  网络蜘蛛

  

  2021/05/23 更新

  演示爬虫目前部署在heroku上,请酌情测试使用

  爬虫模块可以单独调用。有关调用示例,请参见 crawl.test.js。或者 HttpProxy 项目。数据库使用mlab提供的免费远程数据库,速度较慢,请耐心等待。

  操作平台:Linux、MacOS ... Windows 未测试

  基于NodeJS的在线爬虫系统。支持提供在线数据API。

  1、当你想给你的网站添加一个小新闻模块时,可以使用WebSpider爬虫爬取指定网站的数据,然后请求后面的数据接口-end 或 front-end,然后将获取的数据构造到您的网页中。

  2、当你想做一个聚合网站或者聚合app时,可以使用WebSpider爬取各大站点的数据,然后调用API将数据构造成自己的APP。

  ...

  于是,WebSpider 诞生了。

  内容目录功能

  *简单方便。只要对网页有简单的了解,就可以使用WebSpider在线爬虫系统。简单配置后,即可进行数据采集和预览。*强大的。支持抓取预览、自定义输出、生成API、API管理、查看分享、登录注册等功能。*快速响应。爬取结果保存在数据库中,根据用户配置更新响应数据。

  原则

  为了满足爬虫的通用性(即通过页面配置可以爬取多种网站),原理比较简单,就是下载HTML页面进行分析。分析库使用使用 JQuery 核心库的cheerio。可以通过标签选择器和属性选择器获取数据。这样做的限制是无法捕获 Ajax 异步获取的数据。但是,考虑到当今互联网上的大部分Web应用程序还没有过渡到现代应用程序架构,爬虫仍然具有很大的实用价值。

  本地测试

  1、安装 Nodejs、MongoDB、Git、Redis

  2、确保程序有写文件权限

  3、运行代码

  git clone https://github.com/LuckyHH/WebSpider.git

cd WebSpider

npm install

  4、启动 Redis、MongoDB

  5、 修改配置文件(src/config)——自定义启动端口、数据库名、Redis等。

  6、运行 npm start 启动项目

  7. 开放:3000

  项目目录

  |---docs 模块说明文档

| |---env.md 环境说明

| |---issues.md 相关问题说明

| |---proxy.md 代理说明

| |---router.md 接口文档

| |---history.md 更新日志

| |---panel.md 前端面板说明

|---log 日志文件(按天新建日志文件)

| |---error 错误日志

| |---running 运行日志

|---src 源代码

| |---config 配置

| |---index.js 配置项出口控制

| |---dev 开发模式配置项

| |---index.js 开发模式配置项出口

| |---crawl.js 爬虫相关配置项

| |---db.js 数据库配置项

| |---proxy.js 代理配置项

| |---session.js 会话配置项

| |---redis.js redis配置项

| |---api.js API请求频率限制配置

| |---prod 生产模式配置项

| |---test 测试模式配置项

| |---crawl 爬虫

| |---index.js 爬虫主控文件

| |---mapReqUrl.js 并发请求

| |---fetchResult 爬虫核心

| |---proxy 代理

| |---index.js 可用代理检测模块

| |---data 数据目录

| |---config.json 爬虫配置文件

| |---model 数据模型

| |---index.js 模型出口

| |---user.js 用户模型

| |---crawl.js 爬虫模型

| |---statistics.js API统计模型

| |---router Web应用路由

| |---utils 路由部分需要的辅助函数

| |---verification.js 用户输入验证

| |---index.js 路由出口

| |---user.js 用户路由

| |---crawl.js 爬虫接口路由

| |---proxy.js 代理检测路由

| |---utils 辅助函数

| |---index.js 辅助函数出口

| |---debug.js 调试模块

| |---filter.js 用户输入过滤模块

| |---sha.js 加密模块

| |---splice.js 多维数组转化为一维数组

| |---time.js 格式化时间

| |---uuid.js 获取ID模块

| |---isNaN.js 判断参数是否能转化为数字

| |---test 测试文件

| |---crawl.test.js 爬虫测试

| |---router.test.js 路由测试

| |---utils.test.js 功能函数测试

| |---index.js 应用出口

|---static 静态资源文件夹

|---app.js 应用入口

  核心代码

  {superagent.get('').end(function (err, _res) {if (err) {reject(err)}const $=cheerio.load(_res.text)$('.topic_title').each(function (idx, element) {var $element = $(element)items.push({title: $element.attr('title'),url: $element.attr('href'),})})resolve(items )})}) } 否则 {next() }})app.listen(3000)">

  const Koa = require('koa')

const superagent = require('superagent')

const cheerio = require('cheerio')

const app = new Koa()

app.use(async function (ctx, next) {

if (ctx.request.path == '/' && ctx.request.method == 'GET') {

ctx.body = await new Promise((resolve, reject) => {

superagent.get('https://cnodejs.org/').end(function (err, _res) {

if (err) {

reject(err)

}

const $ = cheerio.load(_res.text)

$('.topic_title').each(function (idx, element) {

var $element = $(element)

items.push({

title: $element.attr('title'),

url: $element.attr('href'),

})

})

resolve(items)

})

})

} else {

next()

}

})

app.listen(3000)

  使用 1. 抓取深度

  爬取深度是指从初始 URL 到数据所在 URL 的层数。最大支持爬行深度为3,推荐最大爬行深度为2

  2.网页代码

  登陆页面的编码格式,默认为UTF-8

  3.抓取模式

  普通模式和分页模式

  4.页面范围

  在分页模式下,要获取的开始和结束页码

  5.目标网址

  目标URL是要爬取的目标网站的URL。

  普通模式下,只需要填写要爬取的URL即可。

  在分页模式下:

  填写网址时,将网址中的页码改为*。

  例如:

  CNode 的分页 URL

  改成

  *

  6.选择器

  选择器用于指示数据的位置,可以通过“输出格式”获取目标数据。填写需要用户具备基本的前端知识。

  这里,为了描述方便,将标签选择器分为两种,一种是标签选择器,一种是数据标签选择器。(当然如果你要的数据在一个标签中,那么a标签选择器就是数据标签选择器)

  当爬取深度为1时,可以在一级选择器中填充数据选择器。当爬取深度为2时,一级选择器填充到达二级页面的a标签选择器,二级选择器填充数据标签选择器。当爬取深度为3时,一级选择器填充到达二级页面的a标签选择器,二级选择器填充到达三级页面的a标签选择器,第三级选择器填充到达二级页面的a标签选择器-level 选择器填充数据选择器就是这样。

  填写示例:

  深度 2

  一级选择器:$(".topic_title a")

  辅助选择器:$(".topic .content")

  $(".topic_title a") 指目标页面中类名为topic_title的所有元素中的a元素

  $(".topic .content") 指目标页面中类名topic的元素下类名content的后代元素

  填写二级选择器,表示目标数据在当前页面的下一层(即配置页面的“目标URL”填写的URL),那么一级选择器需要指示到达页面下一层的标签选择器。次要选择器用下一页的数据标签选择器填充

  更多选择器填充规则,参考cheerio。

  7.输出格式

  输出格式是指输出哪些结果。

  在标签选择器指出数据的位置后,需要进一步使用标签选择器和属性选择器来获取数据。

  这需要以 JSON 格式编写。参考写作如下:

  {

"name": "$element.find('.c-9 .ml-20 a').text()",

"age": "$element.children('.c-9').next().text()"

}

  关键部分可以任意指定,值部分需要一定的规则。

  $element 指的是“选择器”中填写的数据标签选择器。(结合"selector"给出的例子,$element指的是$(".topic .content"))

  带键名的值是指被“选择器”过滤的元素下的类名为c-9的元素下的类名ml-20下的a元素中的文本

  键为age的值是指“选择器”过滤的元素下类名为c-9的元素旁边的元素的文本内容

  值得注意的是,当你只需要一种类型的数据时,可以在“Selector”中填写标签选择器时直接将标签定位到目标元素,在“Output Format”中填写属性选择器那就是灿。

  但是很多时候我们需要的数据不止一种,所以在填写“选择器”部分的时候,需要填写的数据标签选择器应该把所有需要的数据都包裹起来,所以你甚至可以填写$("body")比如数据选择器。在“输出格式”的值部分,需要填写一些选择器来表示数据的详细位置,最后使用属性选择器来获取数据。

  同样结合上面给出的例子,

  如果我想获取“名称”值之类的数据,

  那么“选择器”可以这样写

  一级选择器:$(".topic_title a")

  次要选择器:$(".topic .content .c-9 .ml-20 a")

  '输出格式'可以这样写

  {

"name": "$element.text()"

}

  或者

  “选择器”:

  一级选择器:$(".topic_title a")

  次要选择器:$(".topic").find('.content .c-9 .ml-20 a')

  '输出格式':

  {

"name": "$element.text()"

}

  或者

  “选择器”:

  一级选择器:$(".topic_title a")

  次要选择器:$(".topic")

  '输出格式':

  {

"name": "$element.find('.content .c-9 .ml-20 a').text()"

}

  或者

  “选择器”:

  一级选择器:$(".topic_title a")

  辅助选择器:$("body")

  '输出格式':

  {

"name": "$element.find('.topic .content .c-9 .ml-20 a').text()"

}

  常用的属性选择器有 3 种:text()、html() 和 attr()。

  text() 选择目标元素中的文本内容

  html() 选择目标元素的 HTML 代码

  attr() 在目标元素标签中选择一个属性值。参数需要填写,例如$element.attr('url')是指获取目标元素标签中的url属性值

  8.代理模式

  即是否使用HTTP代理来获取数据。有3种模式,内置代理,无代理和自定义代理。

  内置代理使用 thorn 代理或 FreeProxyList 提供的代理地址发出请求。

  自定义代理模式需要用户自己填写可用的代理。

  无代理使用部署服务器 IP 进行请求

  笔记:

  (1)如果自定义代理地址与普通IP地址不匹配,系统默认使用无代理模式。

  (2)代理的质量参差不齐,所以响应可能会失败。所以当响应失败时,请重新提交。

  9.结果预览

  返回结果

  state 表示抓取状态,值为真或假

  时间值是数据的更新时间。

  数据值为抓取结果,格式为数组。

  味精备注

  10.生成API

  数据接口仅在用户登录时生成。点击“生成API”按钮,后台会记录当前爬虫配置,当请求API时,会在适当的情况下调用爬虫进行响应。

  11.更新间隔(后台管理配置项)

  如果两次API调用的间隔在“更新间隔”周期内,则直接调用数据库数据响应,否则调用爬虫响应。所有初始生成的 API 的默认更新间隔为 0,即不更新数据,直接从数据库中读取数据。

  请注意,此项已根据您的需要正确配置。如果“Update Interval”配置值较大或为0,则API平均响应速度快,但时效性较差;配置值小,API平均响应速度慢,但时效性好。

  注意:点击“Generate API”后,在API“Edit”操作中调整“Update Interval”之前,一定要到“Admin Panel”点击一次生成的API链接,完成抓取数据的初始化. 否则,调用 API 返回的结果始终为空。补救措施:当发现返回结果为空时,可以再次进行API“编辑”操作,将“更新间隔”调整为0,点击API链接初始化一次数据,调整“更新间隔”初始化成功后。

  12.标签(后台管理配置项)

  为了方便用户查找某类API,添加标签功能

  13.开启权限(后台管理配置项)

  控制 API 是否共享。API权限开启后,可以在“API Store”面板中看到API信息

  14.描述信息(后台管理配置项)

  API 描述信息。

  数据接口调用示例

  Node.js 后端

  {if (_res.data.state) {res.render('douban', { title: 'douban', content: _res.data.data })} else {res.send('Request failed')}})。catch((err) => {console.error(err)})})">

  const express = require('express')

const axios = require('axios')

const router = express.Router()

router.get('/douban/movie', function (req, res, next) {

axios

.get('http://splider.docmobile.cn/interface?name=luckyhh&cid=1529046160624')

.then((_res) => {

if (_res.data.state) {

res.render('douban', { title: 'douban', content: _res.data.data })

} else {

res.send('请求失败')

}

})

.catch((err) => {

console.error(err)

})

})

  注意:程序后台限制了API调用的频率。为方便起见,示例直接将 API 链接请求结果构造到模板中。实际调用时,请将请求结果保存到redis或数据库中,否则数据响应会失败。

  示例配置参考

  *WebSpider 参考配置

  变更日志

  WebSpider 更新日志

  注意

  https://spider.docmobile.cn/

  对于预览地址,不建议在实际项目中使用。由此造成的损失由用户承担

  TODO协议

  麻省理工学院

0 个评论

要回复文章请先登录注册


官方客服QQ群

微信人工客服

QQ人工客服


线