爬虫攻略(一)

article/2025/10/11 4:56:15

互联网 Web 就是一个巨大无比的数据库,但是这个数据库没有一个像 SQL 语言可以直接获取里面的数据,因为更多时候 Web 是供肉眼阅读和操作的。如果要让机器在 Web 取得数据,那往往就是我们所说的“爬虫”了。现在项目需要,所以研究研究,把大概的过程和“坑”记录下来,也欢迎大渣批评和补充。

爬虫的思路十分简单:

  1. 按照一定的规律发送 HTTP 请求获得页面 HTML 源码(必要时需要加上一定的 HTTP 头信息,比如 cookie 或 referer 之类)
  2. 利用正则匹配或第三方模块解析 HTML 代码,提取有效数据
  3. 将数据持久化到数据库中。

上述过程虽描述得简单,但在实际过程遇到的问题还是不少的,世界上不存在完美的、一致的、通用的抓取工具。为了不同的目的,需要定制不同的代码。下面我们逐一分析。

解析 HTML

简单抓取

最基本的发送 HTTP 请求获得 HTML 代码,使用 node 自带的 http.request 功能即可。如果是爬简单的内容,比如获得某个指定 id 元素中的内容(常见于抓去商品价格),那么正则足以完成任务。但是对于复杂的页面,尤其是数据项较多的页面,使用 DOM 会更加方便高效。

而 node.js 最好的 DOM 实现非 cheerio 莫属了。其实 cheerio 应该算是 jQuery 的一个针对 DOM 操作优化和精简的子集,包含了 DOM 操作的大部分内容,去除了其它不必要的内容。使用 cheerio 你就可以像用普通 jQuery 选择器那样选择你需要的内容。

cheerio 使用方法如下所示,首先引入 cheerio = require('cheerio')。

jsdom 也可以。

var jsdom = require("jsdom");jsdom.env({url: "http://v.youku.com/v_show/id_XMTQ3Mzc1MTczNg==.html?from=y1.6-85.3.1.14b31ff68f3311e5a080&x",
//  ['http://static.youku.com/h5/player/embed/unifull/unifull_.js'],
//  {userAgent:'Mozilla/5.0 (iPhone; CPU iPhone OS 6_0 like Mac OS X) AppleWebKit/536.26 (KHTML, like Gecko) Version/6.0 Mobile/10A5376e Safari/8536.25'
//  },,done:function (err, window) {console.log(err);setTimeout(function(){console.log("there have been", window.document.body.innerHTML);}, 2000);}
});


使用 request.js

request.js 是对 http.request 更高级的封装。如果结合 cheerio 使用,是这样子的。

// 打开详情页
var request = require('request'), cheerio = require('cheerio');function loadInfo(url){request({url: url,headers: {'User-Agent': userAgent}}, function fetch(error, response, body) {if (!error && response.statusCode == 200) {var $ = cheerio.load(body, {decodeEntities: false});var video = $('video');console.log(video);} else {console.log('解析 HTML 错误或通讯故障。');}});
}

详情参阅 request.js 文档以及教程。

JS 生成页面(通过 Phantom.js 抓取)

某些页面的内容显示是通过 JavaScript 动态调用显示的,所以就没法通过普通的获取页面 HTML 然后通过正则或者 XPath 的方式获取到想到的信息了。所幸我们现在有了 Phantom.js 的库,它是一个服务器端的没用界面的 webkit 浏览器。某种程度讲,因为 Phantom.js 内置了一个完整的 JS 运行时,所以这时候是无须要 cheerio 的帮助的。

首先,Phantom.js 不是 node 的库,是可以独立运行的程序——怎么让 Phantom.js 与 Node “联婚”呢?开源的方案搜索一下有不少,例如:

  • https://github.com/SpookyJS/SpookyJS
  • https://github.com/Medium/phantomjs
  • https://github.com/alexscheelmeyer/node-phantom
  • 貌似 Nightmare.js + Electron 也很强大
  • https://github.com/amir20/phantomjs-node

发现只有 phantomjs-node 最近才在更新(最后的那個)。phantomjs-node 成功将 Phantom.js 作为 node 的一个模块来使用,其原理是通过 标准输出 sysin/sysout 来进行两者进程之通讯的(v2.x 改进),速度比较快。既然要依赖于 Phantom.js 那么就要下载 Phantom.js 并将 Phantom.js 配置进环境变量(PATH),命令行输入 phantomjs  如果有反应,那么就可以进行下一步了。

当前 Phantom.js 版本是 2.1,phantomjs-node 版本是 2.0.x。安装 phantomjs-node:

npm install phantom --save

测试是否安装正确(phantomjs.exe 加入 PATH 环境变量)

var phantom = require('phantom');phantom.create().then(function(ph) {ph.createPage().then(function(page) {page.open('https://stackoverflow.com/').then(function(status) {console.log(status);page.property('content').then(function(content) {console.log(content);page.close();ph.exit();})})});
});

下面重点谈谈 Phantom.js 的使用。

Phantom.js

按照上面的例子就可以把 HTML 打印出来(content 内容)。对于 page 打开的页面,往往需要与其进行一些交互,也就是 DOM 方式操控 HTML。page.evaluate() 提供了在page 打开页面的上下文的操作,因此 page.evaluate(function(){...}) 第一个函数是在页面操作的。比如 console.log("foo"),不是在我们 phantomjs 那个控制台里面输出那个文本,而是浏览器的。

注意使用 page.evaluate() 的话一定先要将 JavaScript 激活!

phantomjs-node 提供的 API

phantom.createPage() 方法返回的 page 对象是 Phantom.js 的代理对象,一般情况下其所提供的方法与 Phantom.js 原生的一致。page 的方法为 Promise 异步调用方法,返回的总是一个 Promise 对象。

例如读取某个属性可以调用 page.property(),然后通过 Promise 的 then 异步返回,例如:

page.property('plainText').then(function(content) {console.log(content);
});

设置属性方法如下,then 可以省略。But beware that the next method to phantom will block until it is ready to accept a new message.

page.property('viewportSize', {width: 800, height: 600}).then(function() {  
});

读取属性可以通过以下方法:

page.setting('javascriptEnabled').then(function(value){expect(value).toEqual(true);
});

事件也用通过 property 设置,因为其实它是 page 的一个成员。

page.property('onResourceRequested', function(requestData, networkRequest) {console.log(requestData.url);
})

http://chatgpt.dhexx.cn/article/Se6HIrSA.shtml

相关文章

javascript爬虫

用js爬虫,使用到nodejs 例子中爬取的是中国新闻网时政频道的最新10条新闻的title和链接 事先准备: 1、先去node官网下载安装一下 2、推荐vs code,需要通过终端下载插件,不想的话用cmd小黑框做终端,记事本写代码也行…

用js写个爬虫

如何用js完成爬虫项目 前言一、node.js的安装二、mysql的安装三、确定爬取网页四、查看分析网页源码五、开始写爬虫npmNode调用mysql定义要访问的网站定义新闻页面里具体的元素的读取方式定义哪些url可以作为新闻页面构造一个模仿浏览器的request读取种子页面解析出种子页面里所…

Docker—容器数据卷

目录 1.什么是容器数据卷 2.数据卷的使用 3.实战MySQL同步数据 4.卷 常用命令 5.匿名挂载与具名挂载 5.1 匿名挂载 5.2 具名挂载 6.数据卷容器 1.什么是容器数据卷 Docker将运用与运行的环境打包形成容器运行, Docker容器产生的数据,如果不通过d…

docker删除已停止的容器

一、docker删除已停止的容器 1、根据容器的状态,删除Exited状态的容器 先停止容器、再删除镜像中的容器、最后删除none的镜像。执行命令如下: docker stop $(docker ps -a | grep "Exited" | awk {print $1 }) #停止容器 docker rm $(docke…

Docker与容器的区别

容器 虚拟机和容器结构主要区别在于中间两层,虚拟机自带了操作系统,这个操作系统可以和宿主机一样,也可以不一样,而容器是和宿主机共享一个操作系统。我们知道,操作系统的内容是很多的,就像我们自己电脑上的…

docker 删除 容器/镜像 方法

docker的删除有两种,一个是rm 删除容器,一个是rmi删除镜像 想要删除运行过的images(镜像) 必须首先删除它的container(容器) 首先查看并找到要删除的镜像 docker images 这里我们要删除hello-world镜像 使用rmi 加 镜像id docker rmi fce289e99eb9 报…

docker多容器操作与强制删除容器的方法步骤

简介: 这是一篇有关【doker的多容器操作和强制删除容器的方法】的文章,用最精简的语言去表达给前端读者们。 1、创建多个容器 在WIndows环境下我们来作这个,先打开三个PowerShell窗口,然后在每个窗口中输入创建容器的命令&#…

Docker删除镜像和容器

一、删除容器 首先需要停止所有的容器(只停止单个时把后面的变量改为image id即可) docker stop $(docker ps -a -q) 删除所有的容器(只删除单个时把后面的变量改为image id即可) docker rm $(docker ps -a -q) 二、删除镜像…

如何删除docker镜像与容器

目录 删除示例: 1.查看docker中要删除的镜像 2.删除镜像,使用命令“docker rmi image id” 3.查看docker中正在运行的容器 4.停止容器 5.删除容器 6.查看容器 7.删除镜像 8.最后查看所有镜像 删除示例: 1.查看docker中要删除的镜像 …

docker删除容器日志

废话不多数,看步骤 查看容器日志命令 docker logs -f 容器id 1.进入docker容器目录 cd /var/lib/docker/containers/ 2.查看容器的id,获取容器id,容器id就是容器目录名字 docker ps -a 3.进入容器,删除以.log结尾的文件就是日志文件了&a…

Docker 删除容器

用docker一段时间后,host上可能会有大量已经退出了的容器, 这些容器依然会占用host的文件系统资源,如果确认不会再重启此类容器,可以通过docker rm删除 docker rm一次可以指定多个容器,如果希望批量删除所有已经退出的…

如何优雅地删除Docker镜像和容器(超详细)

一、前言 大家是怎么删除Docker中的镜像和容器的呢,有没有考虑过如何优雅地删除呢?本教程详细指导如何在优雅地删除Docker容器和镜像。如需了解如何在Centos7系统里面安装Docker,可以参考教程【最新Docker在Centos7下安装部署(参考…

AirPlay

最近一直在研究苹果的AirPlay协议。真是个好东西,基本上现在可以把任何屏幕内容,包括音频,视频和屏幕投射到支持AirPlay接收的设备上,目前是Apple TV或者AirExpress。 网上资料很少,比较有用的是这个哥们写的一篇AirPl…

aplay amixer用法详解

aplay aplay -t raw -c 1 -f S16_LE -r 8000 test2.pcm -t: type raw表示是PCM -c: channel 1 -f S16_LE: Signed 16bit-width Little-Endian -r: sample rate 8000 PCM是最raw的音频数据,没有任何头信息。WAV文件就是PCM头信息,头信息就是上述的声道…

aplay amixer arecord说明

arecord声音录制 arecord -l列出声卡和数字音频设备 -D参数用于指定音频设备PCM 以hwx,x开头 根据上面l列出的设备,如果选择tvp5158来录制声音的话那么pcm设备就位hw0,0,如果是tlv320aic3x则pcm设备为hw0,1,sii9135则pcm设备为hw0,2。 声卡号,设备号 -r指定采样频率:5512/8000…

【全志T113-S3_100ask】9-音频输入与输出(amixer、aplay、arecord)

【全志T113-S3_100ask】9-音频输入与输出 背景(一)amixer 的使用(二)amixer 设置音频输出参数(三)使用 aplay 播放音乐(四)使用 arecord 录音 背景 之前查看系统命令,发…

如何使用Aplayer播放器

Aplayer 一、部署 1、Aplayer 官网体验网址:https://aplayer.js.org/ Aplayer的GitHub网址: https://github.com/MoePlayer/APlayer 中文文档手册网址:首页 – APlayer 使用方法很简单,加载Aplayer的js和css,在想…

aplay,arec,amix使用

标准的alsa命令为,aplay,amixer,arecord 如下是高通在mdm9x07芯片上做了客制化的命令 aplay aplay -D hw:0,17 -P &arec arec -D hw:0,17 -P -R 8000 -C 1 &-D card 声卡 -d device 设备 -c channels 通道 -r rate 采样率 -b bits…

Splay

Spaly 众所周知,Splay 是一种平衡二叉查找树(不要告诉我你不知道二叉查找树是什么qwq 不知道什么是二叉查找树的看过来: 关于二叉查找树)。在这篇东西的最后我们也解释了为什么我们需要用到平衡二叉查找树而不是直接查找&#xff…

aplay 源码分析

ffmpeg -formats ffmpeg -sample_fmts ffmpeg -i ../english14.mp3 -ar 44100 -ac 2 -sample_fmt s16 -f wav english14.wav ffmpeg -i ../english14.mp3 -ar 44100 -ac 2 -sample_fmt s16 -f s16le english14.pcm其中针对PCM个数的数据aplay正确的播放格式为: apl…