Browserless 网页抓取:在 Selenium 中使用 NodeJs

news2024/11/24 19:05:46

Selenium 是否有效?

Selenium 是一个流行的开源网页自动化框架,主要用于浏览器测试自动化。此外,它也可以用来解决动态网页抓取问题。

Selenium 有三个主要组件:

  • Selenium IDE:一个浏览器插件,提供了一种更快、更简单的方式来创建、执行和调试 Selenium 脚本。
  • Selenium WebDriver: 一组便携的 API,帮助你用任何编程语言编写在浏览器上运行的自动化测试。
  • Selenium Grid: 自动化工具,用于在多个浏览器、操作系统和平台上分发和扩展测试。

Browserless 对于网页抓取是否好用?

什么是 Browserless?

Nstbrowserless 是一个基于云的无头 Chrome 服务,它执行网页操作并运行自动化脚本,无需图形用户界面。它特别适合自动化任务,如网页抓取和其他自动化过程。

Browserless 对于网页抓取是否好用?

是的,绝对好用!Nstbrowserless 可以在云端完成复杂的网页抓取和其他自动化任务。它会释放你设备的本地服务和存储。Nstbrowserless 通过防检测浏览器和无头 Chrome 特性进行工作。不再需要担心被检测到或遇到网站屏蔽。

将 Browserless 和 Selenium 结合使用,通过让 Selenium 在 Browserless 提供的云端无头 Chrome 环境中运行测试脚本来增强网页自动化。这种设置对于大规模任务,如网页抓取,是有效的,因为它消除了对物理浏览器的需求,同时仍能处理动态内容和用户交互。

你对网页抓取和 Browserless 有什么精彩的想法和疑问吗?
让我们看看其他开发者在 Discord 和 Telegram 上分享了什么吧!

Selenium 网页抓取的优势是什么?

  • 处理动态内容: Selenium 可以与 JavaScript 重的网站进行交互。它允许你抓取在初始页面加载后动态加载的内容。
  • 浏览器自动化: Selenium 可以模拟用户与网站的实际交互,例如点击按钮、填写表单和导航页面,使其非常适合抓取需要用户交互的网站的数据。
  • 多浏览器支持: Selenium 支持多种浏览器(Chrome、Firefox、Safari),因此你可以在不同环境中进行测试和抓取。
  • 编程语言灵活性: Selenium 与多种编程语言兼容,包括 Python、Java、C# 和 JavaScript,这为开发者提供了选择其首选语言的灵活性。
  • 绕过反抓取措施: Selenium 模拟真实用户行为的能力使其能够有效绕过一些旨在防止自动化抓取的反抓取措施,例如 CAPTCHA 和限流。
  • 实时数据收集: 使用 Selenium,你可以实时抓取和收集数据,这对于时间敏感的应用非常有用。
  • 广泛的社区和文档: Selenium 拥有一个庞大且活跃的社区,以及广泛的文档,帮助解决问题并提高你的网页抓取项目的效率。

如何在 Selenium 中使用 NodeJS?

通过在 Selenium 中使用 Node.js,开发者可以控制无头 Chrome 执行各种操作,如网页抓取、自动化测试、生成屏幕截图等。

这种组合利用了 Node.js 的高效非阻塞特性和无头 Chrome 的浏览器能力,实现高效的自动化和数据处理。

步骤 1. 安装

在终端中输入以下命令:

npm install selenium-webdriver

如果终端报告错误,请检查你的计算机是否有 node 环境:

node --version

没有 node 环境?请先安装最新版本的 node 环境。

步骤 2. 使用 NodeJS 在 Selenium 中运行浏览器

Selenium 以其强大的浏览器自动化能力而闻名。它支持大多数主要浏览器,包括 Chrome、Firefox、Edge、Opera、Safari 和 Internet Explorer。

由于 Chrome 是其中最受欢迎和最强大的浏览器,你将在本教程中使用它。

import { Builder, Browser } from 'selenium-webdriver';

async function run() {
    const driver = new Builder()
      .forBrowser(Browser.CHROME)
      .build();
    await await driver.get('https://www.yahoo.com/');
}

你还可以添加任何个性化的设置。让我们将脚本设置为无头 Chrome:

import { Builder, Browser } from 'selenium-webdriver';
import chrome from 'selenium-webdriver/chrome';
 
const options = new chrome.Options();
options.addArguments('--remote-allow-origins=*');
options.addArguments('--headless');

async function run() {
    const driver = new Builder()
      .setChromeOptions(options)
      .forBrowser(Browser.CHROME)
      .build();
    await await driver.get('https://www.yahoo.com/');
}

现在,你可以访问任何网站了!

步骤 3. 抓取网站

一旦你有了网页的完整 HTML,你可以继续提取所需的数据。在这种情况下,让我们解析页面上所有新闻的标题和内容。

为完成此任务,你必须执行以下步骤:

  • 使用 DevTools 分析网页的 DOM。
  • 实现有效的节点选择策略以定位新闻。
  • 提取所需数据并将其存储在 JavaScript 数组/对象中。

DevTools 是网页抓取中一个宝贵的工具。它帮助你检查当前加载的 HTML、CSS 和 JavaScript。你还可以获得有关页面网络请求及其对应加载时间的信息。

CSS 选择器和 XPath 表达式是最可靠的节点选择策略。你可以使用其中任何一个来定位元素,但在本教程中,为了简单起见,我们将使用 CSS 选择器。

让我们使用 DevTools 查找正确的 CSS 选择器。在浏览器中打开目标网页右键点击产品元素 > 检查以打开 DevTools

你可以看到每个新闻标题的结构由一个 h3 标签和 a 标签组成,我们可以使用选择器 h3[data-test-locator="stream-item-title"] 来定位它们。

我们使用相同的方法查找选择器 p[data-test-locator="stream-item-summary"] 用于新闻内容。

使用上述信息定义 CSS 选择器,并通过 findElements() 和 findElement() 方法定位产品。

此外,使用 getText() 方法提取 HTML 节点的内文本,最后将提取的名称和价格存储在一个数组中。

const titlesArray = [];
const contentArray = [];

const newsTitles = await driver.findElements(By.css('h3[data-test-locator="stream-item-title"]'));
const newsContents = await driver.findElements(By.css('p[data-test-locator="stream-item-summary"]'));

for (let title of newsTitles) {
    titlesArray.push(await title.getText());
}

for (let content of newsContents) {
    contentArray.push(await content.getText());
}

步骤 4. 导出数据

我们已经获得了网页抓取的数据!现在,我们需要将它们导出到一个 CSV 文件中。

导入内置的 Node.js fs 模块,该模块提供了处理文件系统的函数:

import fs from 'node';

然后,初始化一个名为 newsData 的字符串变量,其中包含一个包含列名的标题行("title, content\n")。

let newsData = 'title,content\n';

接下来,循环遍历包含新闻标题和内容的两个数组(titlesArray 和 contentsArray)。对于数组中的每个元素,在 newsData 后附加一行,用逗号分隔标题和内容。

for (let i = 0; i < titlesArray.length; i++) {
    newsData += `${titlesArray[i]},${contentsArray[i]}\n`;
}

使用 fs.writeFile() 函数将 newsData 字符串写入名为 yahooNews.csv 的文件中。此函数接受三个参数:文件名要写入的数据处理写入过程中遇到的任何错误的回调函数

fs.writeFile("yahooNews.csv", newsData, err => {
    if (err) {
        console.error("Error:", err);
    } else {
        console.log("Success!");
    }
});

运行我们的代码,我们会得到类似于以下的结果:

恭喜你,已经学会了如何使用 Selenium 和 HeadlessChrome: NodeJS 进行网页抓取。

如何避免在使用 Browserless 抓取时被封锁?

在 Browserless 中使用 headlesschrome 模式可以最大限度地自动避免网页检测和封锁。但请结合以下策略以获得更高效的抓取和无缝体验。

  • 模拟真实用户行为

以下是一个使用 Selenium 和 Node.js 模拟真实用户行为的示例代码。代码展示了如何设置 User-Agent、模拟鼠标操作、处理动态内容、模拟键盘输入和控制浏览器行为。

在使用之前,请确保已安装 selenium-webdriver 和 chromedriver

const { Builder, By, Key, until } = require('selenium-webdriver');
const chrome = require('selenium-webdriver/chrome');
const path = require('path');

// 启动浏览器
(async function example() {
  // 配置 Chrome 选项
  let chromeOptions = new chrome.Options();
  chromeOptions.addArguments('headless'); // 使用 headless 模式
  chromeOptions.addArguments('window-size=1280,800'); // 设置浏览器窗口大小

  // 创建 WebDriver 实例
  let driver = await new Builder()
    .forBrowser('chrome')
    .setChromeOptions(chromeOptions)
    .build();

  try {
    // 设置 User-Agent 和其他请求头
    await driver.executeCdpCmd('Network.setUserAgentOverride', {
      userAgent: 'Your Custom User-Agent',
    });

    // 导航到目标页面
    await driver.get('https://example.com');

    // 模拟鼠标移动和点击
    let element = await driver.findElement(By.css('selector-for-clickable-element'));
    await driver.actions().move({ origin: element }).click().perform();

    // 随机等待时间
    function sleep(ms) {
      return new Promise(resolve => setTimeout(resolve, ms));
    }
    await sleep(Math.random() * 5000 + 2000); // 随机等待 2 到 7 秒

    // 处理动态内容并等待特定元素加载
    await driver.wait(until.elementLocated(By.css('#dynamic-content')), 10000);

    // 模拟键盘输入
    let searchInput = await driver.findElement(By.css('#search-input'));
    await searchInput.sendKeys('Node.js', Key.RETURN);

    // 随机滚动
    await driver.executeScript('window.scrollBy(0, window.innerHeight);');

  } finally {
    // 关闭浏览器
    await driver.quit();
  }
})();
  • 使用代理

使用代理服务器隐藏实际的 IP 地址可以有效避免 IP 封锁。你可以选择轮换代理,以在每次请求时使用不同的 IP 地址,从而减少被封锁的风险。

  • 限制抓取频率

控制抓取频率,以避免在短时间内发送大量请求,这可以减少触发反爬虫机制的机会。你可以设置适当的时间间隔来发送请求,以模拟正常的浏览行为。

  • 绕过 CAPTCHA

如果网站使用 CAPTCHA 进行保护,你可以使用第三方 CAPTCHA 识别服务自动解决这些挑战,或者配置 Selenium 以处理 CAPTCHA。

  • 隐藏真实浏览器指纹

一些网站使用浏览器指纹来识别自动化工具。配置不同的浏览器指纹或使用内置指纹切换的 反检测浏览器可以帮助绕过网站检测。

  • 处理动态加载的内容

使用 Browserless 结合 Selenium 处理动态加载的内容(如 AJAX 请求)可以确保捕获网页上的所有动态渲染数据,而不仅仅是静态内容。

使用 Selenium 进行其他网页操作

1. 定位元素

Selenium 本身提供了多种方法来查找页面元素,包括:

  • 按标签名查找:按元素的标签名搜索,如 <input> 或 <button>,适合广泛搜索。
  • 按 HTML 类名查找:使用元素的 CSS 类名搜索,如 .class-name,适合快速定位具有特定类名的元素。
  • 按 ID 查找:按元素的唯一 ID 搜索,如 #element-id,特别适合快速准确地找到特定元素。
  • 使用 CSS 选择器:使用 CSS 选择器语法查找元素,可以选择具有特定属性、类名或结构的元素,如 div > p.class-name
  • 使用 XPath 表达式:通过 XPath 路径查找元素,允许精确导航页面结构,如 //div[@id='example']

因此,在 Selenium WebDriver 中,我们可以通过 find_element 方法在网页上定位元素。你只需在使用时添加具体要求。例如:

  • find_element_by_id:按唯一 ID 查找元素。
  • find_element_by_class_name:按 CSS 类名查找元素。
  • find_element_by_link_text:按链接文本查找超链接元素。

2. 等待元素

在某些情况下,如网络或浏览器缓慢,你的脚本可能会失败或显示不一致的结果。

不要等到固定的时间间隔,而是选择智能等待,如等待特定节点出现或显示在页面上。这可以确保在与元素交互之前,网页元素已正确加载,从而减少 element not found 和 element not interactable 等错误的机会。

以下代码片段实现了等待策略。until.elementsLocated 方法定义了等待条件,确保 WebDriver 等待直到指定的元素找到或达到最大等待时间 5000 毫秒(5 秒)。

const { Builder, By, until } =  require('selenium-webdriver');

const yourElements = await driver.wait(until.elementsLocated(By.css('.your-css-selector')), 5000);

3. 截图

在 NodeJS 中,你可以通过调用一个函数来截图。然而,有一些考虑事项以确保截图正确捕获:

  • 窗口大小:确保浏览器窗口大小适合你需要捕获的内容。如果窗口太小,页面的部分内容可能会被截断。
  • 页面加载完成:在截图之前,确认所有异步 HTTP 请求已完成,页面已完全渲染。这确保截图准确反映页面的最终状态。
import fs from 'node';
import { Builder, Browser } from 'selenium-webdriver';

async function screenshot() {
    const driver = new Builder()
      .forBrowser(Browser.CHROME)
      .build();

    await driver.get('https://www.yahoo.com/');
    const pictureData = await driver.takeScreenshot();
    
    fs.writeFileSync('screenshot.png', pictureData, 'base64');
}

screenshot();

4. 执行自定义 JavaScript 命令

使用像 Selenium 这样的浏览器自动化工具的一个突出特点是可以利用浏览器自身的 JavaScript 引擎。这意味着你可以在你与之交互的网页上下文中注入和执行自定义的 JavaScript 代码。

const javascript = 'window.scrollBy(100, 100)';
await driver.executeScript(javascript);

最终想法

在本 Selenium Node.js 教程中,你学习了如何使用 headlesschrome 和 Selenium 来设置一个 Node.js WebDriver 项目,从动态网站中抓取数据,处理动态内容,并解决常见的网页抓取挑战。

现在是建立你自己的网页抓取流程的好时机!借助 Nstbrowser RPA,一切复杂的任务将会得到简化。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2058886.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

「JVS更新日志」逻辑引擎、智能BI、规则引擎8.20功能更新说明

项目介绍 JVS是企业级数字化服务构建的基础脚手架&#xff0c;主要解决企业信息化项目交付难、实施效率低、开发成本高的问题&#xff0c;采用微服务配置化的方式&#xff0c;提供了 低代码数据分析物联网的核心能力产品&#xff0c;并构建了协同办公、企业常用的管理工具等&am…

单域名SSL证书申请三步法

申请单域名SSL证书&#xff0c;确保您的网站安全可信&#xff0c;只需简单三步&#xff1a; 选择证书类型与提供商&#xff1a;首先&#xff0c;确定您需要的单域名SSL证书类型&#xff0c;如DV&#xff08;域名验证&#xff09;证书。接着&#xff0c;选择一个信誉良好的证书提…

笔记-系统规划与管理师-案例题-2022年-服务规划设计

【说明】 某跨国公司新聘小唐为系统规划管理师来帮助提升中国区总部的IT服务水平&#xff0c;中国区的IT系统尚在设计阶段&#xff0c;小唐需根据已经识别的服务需求及设定的服务级别&#xff0c;进行资源配置&#xff0c;以确保服务团队满足与业务团队约定的当前及未来的IT服务…

Grafana指标汉化攻略:轻松实现中文可视化

1、Grafana解压 目录&#xff08;grafana-v11.1.3&#xff09; 进入到\conf 2、找到&#xff1a;defaults.ini 3、打开defaults.ini &#xff0c;搜索&#xff1a;en-US 4、注释掉default_language en-US # Default UI language (supported IETF language tag, such as en…

吐血整理,最全论文指令手册,还有 ChatGPT 3.5/4.0 新手使用手册~ 【亲测好用】

今天给大家分享下论文润色、降重、写作的GPT指令提示词&#xff0c;按论文步骤整理 让你的文章更加有逻辑且通顺&#xff0c;助力快速完成论文&#xff0c;相信对你有帮助~ 一、论文写作润色指令 1、写作选题指令 ① 确定研究对象 我是一名【XXXXX】&#xff0c;请从以下素…

新书上架 | 《智能计算系统:从深度学习到大模型(第2版)》重磅上市!

欢迎关注博主 Mindtechnist 或加入【智能科技社区】一起学习和分享Linux、C、C、Python、Matlab&#xff0c;机器人运动控制、多机器人协作&#xff0c;智能优化算法&#xff0c;滤波估计、多传感器信息融合&#xff0c;机器学习&#xff0c;人工智能等相关领域的知识和技术。关…

多元统计分析——基于R的笔记本电脑价格与参数可视化

注&#xff1a;能力有限&#xff0c;存在不足之处。 现如今&#xff0c;笔记本电脑现在已经成为了我们日常生活中所必备的一种工具&#xff0c;使用笔记本既可以为我们在学习上带来便利也可以在为我们在工作上带来便利&#xff0c;但是笔记本的价格与许多参数有关&#xff0c;因…

构建个人编程学习的知识宝库:高效笔记记录与整理策略

文章目录 每日一句正能量前言笔记工具选择笔记结构设计实践与复习策略后记 每日一句正能量 人生之美&#xff0c;不在争求&#xff0c;而在静守。只愿此心&#xff1a;一世清宁&#xff0c;安然盛开&#xff01; 前言 在编程的广阔天地中&#xff0c;我们如同探险者&#xff0…

Stable Diffusion最强插件ControlNet简介

前言 随着人工智能技术的飞速发展&#xff0c;图像生成已经成为了一个热门领域。在这其中&#xff0c;Stable Diffusion插件ControlNet凭借其创新的技术和强大的功能&#xff0c;获得了一致好评。 所有的AI设计工具&#xff0c;模型和插件&#xff0c;都已经整理好了&#xff…

SpringBoot笔记01

第1章 Spring Boot概要 1.1 SpringBoot介绍 随着动态语言的流行&#xff08;Ruby、Scala、Node.js&#xff09;, Java的开发显得格外的笨重&#xff1b;繁多的配置、低下的开 发效率、复杂的部署流程以及第三方技术整合难度大。 在上述环境下&#xff0c;Spring Boot由此诞生…

《Techporters架构搭建》-Day06 Springboot国际化

Springboot国际化 什么是国际化&#xff1f;为什么使用国际化&#xff1f;国际化细分国际化相关知识Locale对象MessageSource接口LocaleResolver接口国际化文件 国际化一般实现国际化改进版框架中国际化 源码地址&#xff1a;请看day06 什么是国际化&#xff1f; 国际化&#…

Ubuntu24.04用C++ Connector连接MySQL数据库

首先安装MySQL官方提供的C Connector库。 sudo apt-get install libmysqlcppconn-dev 然后找一个目录&#xff0c;建立一个main.cpp文件。 #include <iostream> #include <mysql_driver.h> #include <mysql_connection.h> #include <cppconn/statemen…

vscode提升:JSON 中不允许有注释

解决方案 &#xff1a; 运行&#xff1a; json with comment 参考链接&#xff1a; https://blog.csdn.net/eqizhihui/article/details/134014010 人工智能学习网站 https://chat.xutongbao.top

逆变器的防孤岛测试基础知识

防孤岛测试是逆变器并网前的重要测试项目&#xff0c;主要用于验证并网发电系统在电网断电的情况下&#xff0c;能否快速、准确地检测到电网的失电状态&#xff0c;并在规定的时间内停止向电网输送电能&#xff0c;以防止电力系统出现孤岛效应。 孤岛效应是指当电网因故障或停电…

Chainlit接入FastGpt接口快速实现自定义用户聊天界面

前言 由于fastgpt只提供了一个分享用的网页应用&#xff0c;网页访问地址没法自定义&#xff0c;虽然可以接入NextWeb/ChatGPT web等开源应用。但是如果我们想直接给客户应用&#xff0c;还需要客户去设置配置&#xff0c;里面还有很多我们不想展示给客户的东西怎么办&#xf…

数论(二)——博弈论与组合计数

文章目录 4题单A - [有趣的数](https://www.acwing.com/problem/content/description/3198/)B - [取数游戏 II](https://www.luogu.com.cn/problem/P1288)C - [acwing-nim](https://www.acwing.com/problem/content/submission/code_detail/29453954/)D - [排列计数](https://w…

C语言小tip之整型提升

今天让我们来学习一下C语言中的一个小知识点-----整型提升 什么叫整型提升呢&#xff1f; C语言中整型算术运算总是至少以缺省&#xff08;默认&#xff09;整型类型的精度来进行的。​为了获得这个精度&#xff0c;表达式中的字符和短整型操作数在使用之前被转换为普通整型&a…

从大模型到通用AI《智能计算系统》带你揭秘大模型背后的智能计算革命

“只要你想把大模型做得更好、做得更大、做得更快、做得更省电&#xff0c;你就必须要有系统的人才跟思维。 . 我们这个领域变化得特别快,教的内容,教的方式,都要不断地变化。如果我们中国的研究者和教育者做得更好一点如果我们在具身智能的大模型上,或者是说在未来终极的通用人…

AI预测福彩3D采取888=3策略+和值012路或胆码测试8月21日新模型预测第63弹

经过62多期的测试&#xff0c;当然有很多彩友也一直在观察我每天发的预测结果&#xff0c;得到了一个非常有价值的信息&#xff0c;那就是9码定位的命中率非常高&#xff0c;62多期一共只错了6次&#xff0c;这给喜欢打私房菜的朋友提供了极高价值的预测结果~当然了&#xff0c…

【JVM】JVM解析字节码文件过程(二)

JVM解析字节码文件过程 字节码中的数据结构 field_info 在Java字节码中&#xff0c;field_info结构是用来描述类或接口中的字段(成员变量的)。每个field_info结构对应类文件中的一个字段。其中它的组成部分包括如下&#xff1a; 1.access_flags:访问标志,表示字段的访问级别(如…