既然有Python,为什么还要用JavaScript解析数据?
\n\n你好,朋友!如果你正在阅读这段文字,那么很可能你已经熟悉Python及其BeautifulSoup或Scrapy等库。但如果你遇到了Python无法解决的问题呢?例如,需要从一个完全基于React或Angular构建的网站收集数据。所有信息都通过JavaScript加载,而原始HTML中空空如也。这时,JavaScript就登场了!
\n\nJavaScript数据解析与抓取不仅仅是一种流行趋势,而是处理现代Web应用程序的迫切需求。Node.js允许你在服务器上直接运行浏览器引擎,处理DOM,点击按钮,并等待异步内容加载。在本文中,我们将分析真实工具并编写可直接用于你项目的代码。
\n\n准备好将JavaScript变成强大的数据吸尘器了吗?我们开始吧!
\n\n\n\n
JavaScript抓取的主要工具
\n\n在编写代码之前,让我们先认识一下我们武器库中的主要“战士”。对于JavaScript数据解析,我们将使用三大支柱:
\n\n- \n
- Axios — 用于发送请求和获取页面HTML代码的HTTP客户端。 \n
- Cheerio — 快速轻量级的HTML解析库,在服务器上像jQuery一样工作。 \n
- Puppeteer — 完整的无头浏览器(Chrome),能够执行JavaScript、点击、滚动和等待。 \n
对于静态页面,Axios + Cheerio就足够了。如果网站通过AJAX加载数据或需要授权,请使用Puppeteer。现在让我们进入实践。
\n\n\n\n
示例1:使用Cheerio简单解析静态页面
\n\n假设我们需要从一个直接返回HTML(无动态内容)的网站收集新闻标题。安装依赖:
\n\nnpm install axios cheerio\n\n现在编写一个脚本,从主页提取所有h2标题(将URL替换为真实地址):
\n\nconst axios = require('axios');\nconst cheerio = require('cheerio');\n\nasync function parseStaticPage(url) {\n try {\n const { data } = await axios.get(url);\n const $ = cheerio.load(data);\n\n const titles = [];\n $('h2').each((i, el) => {\n titles.push($(el).text().trim());\n });\n\n console.log('找到的标题:');\n titles.forEach((title, index) => {\n console.log(`${index + 1}. ${title}`);\n });\n } catch (error) {\n console.error('解析错误:', error.message);\n }\n}\n\nparseStaticPage('https://example.com/news');\n\n这段代码是基础,你应该从这里开始学习JavaScript数据抓取。Cheerio运行极快,但无法执行脚本。如果网站显示“加载中...”,请继续阅读。
\n\n\n\n
示例2:使用Puppeteer解析动态页面
\n\n现在想象一下,数据只有在用户滚动页面或点击“显示更多”按钮后才出现。对于这类任务,Puppeteer是理想选择。安装它:
\n\nnpm install puppeteer\n\n场景:进入商品页面,等待3秒(等待JS加载),然后收集商品名称:
\n\nconst puppeteer = require('puppeteer');\n\nasync function parseDynamicPage(url) {\n const browser = await puppeteer.launch({ headless: true });\n const page = await browser.newPage();\n\n await page.goto(url, { waitUntil: 'networkidle2' });\n // 等待内容出现(选择器 .product-title)\n await page.waitForSelector('.product-title', { timeout: 10000 });\n\n const items = await page.evaluate(() => {\n const titles = [];\n document.querySelectorAll('.product-title').forEach(el => {