浏览器中JavaScript爬虫不可行,因受同源策略和CORS限制;Node.js配合axios+cheerio可实现静态页面抓取,动态内容需puppeteer;法律合规(robots.txt、ToS)与反爬应对同等重要。

JavaScript 爬虫不能直接在浏览器里写、也不能靠 fetch 跨域抓取目标网站(除非对方显式允许),但可以用 Node.js 搭配合适库实现真正可用的爬虫。核心限制不在语言,而在运行环境和反爬机制。
为什么浏览器里写 JS 抓不了多数网页?
浏览器发起的 fetch 或 XMLHttpRequest 受同源策略和 CORS 限制:目标网站没配 Access-Control-Allow-Origin,请求就会被拦在前端。这不是代码写得不对,是浏览器故意不让你跨域读数据。
- 你看到的 “CORS error” 或 “Blocked by CORS Policy” 就是这个原因
-
document.querySelector只能操作当前页面 DOM,不能读别人家网页的 HTML - 想绕过?必须换环境——用 Node.js 启动服务端请求,它不受浏览器同源策略约束
Node.js 下怎么写一个基础爬虫?
推荐用 axios + cheerio 组合:前者发 HTTP 请求拿 HTML,后者像 jQuery 一样解析 DOM。比 Puppeteer 轻量,适合静态页面。
安装依赖:
立即学习“Java免费学习笔记(深入)”;
npm install axios cheerio
简单示例(抓取某新闻列表标题):
const axios = require('axios');
const cheerio = require('cheerio');
axios.get('https://example-news-site.com')
.then(res => {
const $ = cheerio.load(res.data);
$('h2.title').each((i, elem) => {
console.log($(elem).text().trim());
});
})
.catch(err => console.error('请求失败:', err.message));
- 注意加
.trim(),很多网站 HTML 里标题前后有空格或换行 - 如果目标站有反爬(如校验
User-Agent),得手动加请求头:headers: { 'User-Agent': 'Mozilla/5.0...' } -
cheerio不执行 JS,所以动态渲染的内容(比如用 React/Vue 加载的列表)抓不到——这时得换puppeteer
遇到 JavaScript 渲染的页面怎么办?
用 puppeteer 启动真实 Chromium 实例,等页面 JS 执行完再取 DOM。代价是启动慢、内存高、部署麻烦,但能处理 SPA 或懒加载内容。
关键点:
- 必须等关键元素出现,不能一拿到 HTML 就解析 —— 用
page.waitForSelector('article.list-item') - 记得调用
browser.close(),否则进程常驻吃光内存 - 服务器上运行需额外装 Chromium(Docker 镜像常用
cypress/included或puppeteer官方镜像) - 有些网站会检测
puppeteer特征(如navigator.webdriver),得用page.evaluateOnNewDocument伪造
法律和工程风险比技术更关键
能写出来 ≠ 应该跑。重点不是“怎么抓”,而是“能不能抓”:
- 先看目标站
robots.txt(如https://example.com/robots.txt),里面Disallow:的路径别碰 - 检查其
Terms of Service,很多明确禁止自动化采集 - 加
setTimeout控制请求频率,别一秒刷 10 次 —— 这会被当攻击封 IP - 返回 429(Too Many Requests)或 403 就立刻停,别 retry 死磕
真正难的从来不是解析 HTML,而是让爬虫不被发现、不被封、不踩红线。参数调得再细,也得先看清楚对方的规则文件和响应头里的 X-Robots-Tag。











