返回博客
指南
Raluca Penciuc2023年2月23日阅读时间:9分钟

《沃尔玛网页抓取终极指南》

《沃尔玛网页抓取终极指南》

先决条件

在开始之前,请确保已准备好必要的工具。

首先,请从官方网站下载并安装 Node.js,务必选用长期支持(LTS)版本。此操作将自动安装 Node 包管理器(NPM),我们后续将通过它安装其他依赖项。

在本教程中,我们将使用 Visual Studio Code 作为集成开发环境(IDE),但您也可以选择使用任何其他 IDE。为您的项目创建一个新文件夹,打开终端,并运行以下命令来设置一个新的 Node.js 项目:

npm init -y

这将在项目目录中生成一个 package.json 文件,用于存储项目及其依赖项的相关信息。

接下来,我们需要安装 TypeScript 以及 Node.js 的类型定义。TypeScript 提供了可选的静态类型检查功能,有助于防止代码中的错误。为此,请在终端中运行:

npm install typescript @types/node --save-dev

您可以通过运行以下命令验证安装是否成功:

npx tsc --version

TypeScript 使用名为 tsconfig.json 的配置文件来存储编译器选项及其他设置。要在项目中创建此文件,请运行以下命令:

npx tsc -init

请确保将“outDir”的值设置dist”。这样,我们将把 TypeScript 文件与编译后的文件分开。您可以在 TypeScript 官方文档中找到有关此文件及其属性的更多信息。

现在,在项目中创建一个“src”目录,并新建一个“index.ts”文件。我们将在此保存爬取代码。要执行 TypeScript 代码,必须先进行编译,因此为了确保不会遗漏这一步,我们可以使用自定义命令。

请打开“package.json”文件,并将“scripts”部分修改如下:

"scripts": {

    "test": "npx tsc && node dist/index.js"

}

这样,当你需要运行脚本时,只需在终端中输入“npm run test”即可。

最后,为了从网站抓取数据,我们将使用 Puppeteer。这是一个适用于 Node.js 的无头浏览器库,允许您通过编程方式控制网页浏览器并与网站进行交互。要安装它,请在终端中运行以下命令:

npm install puppeteer

强烈建议在确保数据完整性时使用该工具,因为如今许多网站都包含动态生成的内容。如果您感兴趣,可以在继续之前查阅 Puppeteer 文档,全面了解其功能。

定位数据

现在环境已配置完毕,我们可以开始探讨如何提取数据了。本文中,我选择从这个产品页面抓取数据:https://www.walmart.com/ip/Keter-Adirondack-Chair-Resin-Outdoor-Furniture-Teal/673656371

我们将提取以下数据:

  • 产品名称;
  • 产品评分;
  • 产品评论数量;
  • 产品价格;
  • 产品图片;
  • 产品详情。

您可以在下方的截图中看到所有这些信息已被标出:

Walmart product page for an outdoor Adirondack chair, with red boxes highlighting the image gallery, product title and price, and the description section

通过在每个元素上打开开发者工具,您将能够看到我们将用于定位 HTML 元素的 CSS 选择器。如果您对 CSS 选择器的运作机制还不太熟悉,欢迎查阅这篇入门指南

数据提取

在编写脚本之前,让我们先验证一下 Puppeteer 的安装是否成功:

import puppeteer from 'puppeteer';

async function scrapeWalmartData(walmart_url: string): Promise<void> {

    // Launch Puppeteer

    const browser = await puppeteer.launch({

        headless: false,

    	  args: ['--start-maximized'],

    	  defaultViewport: null

    })

    // Create a new page

    const page = await browser.newPage()

    // Navigate to the target URL

    await page.goto(walmart_url)

    // Close the browser

    await browser.close()

}

scrapeWalmartData("https://www.walmart.com/ip/Keter-Adirondack-Chair-Resin-Outdoor-Furniture-Teal/673656371")

这里我们打开一个浏览器窗口,新建一个页面,导航至目标 URL,然后关闭浏览器。为了简化操作和便于可视化调试,我以非无头模式全屏打开了浏览器窗口。

现在,让我们看看网站的结构:

Walmart product page alongside browser inspector, highlighting the product title, price, and corresponding HTML elements

要获取产品名称,我们锁定“h1”元素的“itemprop”属性。我们需要提取的是其文本内容。

// Extract product name

const product_name = await page.evaluate(() => {

    const name = document.querySelector('h1[itemprop="name"]')

    return name ? name.textContent : ''

})

console.log(product_name)

对于评分数值,我们确定了类名以“rating-number”结尾的“span”元素是可靠的。

// Extract product rating number

const product_rating = await page.evaluate(() => {

    const rating = document.querySelector('span[class$="rating-number"]')

    return rating ? rating.textContent : ''

})

console.log(product_rating)

最后(针对高亮部分),对于评论数量和产品价格,我们同样依赖“itemprop”属性,与上述方法一致。

// Extract product reviews count

const product_reviews = await page.evaluate(() => {

    const reviews = document.querySelector('a[itemprop="ratingCount"]')

    return reviews ? reviews.textContent : ''

})

console.log(product_reviews)

// Extract product price

const product_price = await page.evaluate(() => {

    const price = document.querySelector('span[itemprop="price"]')

    return price ? price.textContent : ''

})

console.log(product_price)

接下来处理产品图片,我们需要在 HTML 文档中进一步定位:

Walmart product page with the image thumbnail carousel highlighted, and browser inspector showing the selected image element

这稍显棘手,但并非无法实现。仅凭图片本身无法唯一识别,因此这次我们将锁定其父级元素。于是,我们提取那些“data-testid”属性值设为“media-thumbnail”的“div”元素。

随后,我们将结果转换为 JavaScript 数组,以便将每个元素与其“src”属性建立映射。

// Extract product images

const product_images = await page.evaluate(() => {

    const images = document.querySelectorAll('div[data-testid="media-thumbnail"] > img')

    const images_array = Array.from(images)

    return images ? images_array.map(a => a.getAttribute("src")) : []

})

console.log(product_images)

最后但同样重要的是,我们向下滚动页面以查看产品详情:

Walmart product details section highlighted, with browser inspector showing the HTML for the description and bullet list content

我们应用与提取图片相同的逻辑,这次只需利用类名“dangerous-html”。

// Extract product details

const product_details = await page.evaluate(() => {

    const details = document.querySelectorAll('div.dangerous-html')

    const details_array = Array.from(details)

    return details ? details_array.map(d => d.textContent) : []

})

console.log(product_details)

最终结果应如下所示:

Keter Adirondack Chair, Resin Outdoor Furniture, Teal

(4.1)

269 reviews

Now $59.99

[

'https://i5.walmartimages.com/asr/51fc64d9-6f1f-46b7-9b41-8880763f6845.483f270a12a6f1cbc9db5a37ae7c86f0.jpeg?odnHeight=80&odnWidth=80&odnBg=FFFFFF',  'https://i5.walmartimages.com/asr/80977b5b-15c5-435e-a7d6-65f14b2ee9c9.d1deed7ca4216d8251b55aa45eb47a8f.jpeg?odnHeight=80&odnWidth=80&odnBg=FFFFFF',

'https://i5.walmartimages.com/asr/80c1f563-91a9-4bff-bda5-387de56bd8f5.5844e885d77ece99713d9b72b0f0d539.jpeg?odnHeight=80&odnWidth=80&odnBg=FFFFFF',  'https://i5.walmartimages.com/asr/fd73d8f2-7073-4650-86a3-4e809d09286e.b9b1277761dec07caf0e7354abb301fc.jpeg?odnHeight=80&odnWidth=80&odnBg=FFFFFF',

'https://i5.walmartimages.com/asr/103f1a31-fbc5-4ad6-9b9a-a298ff67f90f.dd3d0b75b3c42edc01d44bc9910d22d5.jpeg?odnHeight=80&odnWidth=80&odnBg=FFFFFF',  'https://i5.walmartimages.com/asr/120121cd-a80a-4586-9ffb-dfe386545332.a90f37e11f600f88128938be3c68dca5.jpeg?odnHeight=80&odnWidth=80&odnBg=FFFFFF',

'https://i5.walmartimages.com/asr/47b8397f-f011-4782-bbb7-44bfac6f3fcf.bb12c15a0146107aa2dcd4cefba48c38.jpeg?odnHeight=80&odnWidth=80&odnBg=FFFFFF'

]

[

  'The Keter Adirondack chair lets you experience the easy-living comfort of the popular chair but with none of the worries of wood. Combining traditional styling and the look and feel of wood with durable and maintenance-free materials, this chair will find',

  'Keter Adirondack Chair, Resin Outdoor Furniture, Gray:   Made from an all-weather resistant resin for ultimate durability  Weather-resistant polypropylene construction prevents fading, rusting, peeling, and denting - unlike real wood  Quick and easy assembly  Rotating cup holder  Classic comfort redefined  Ergonomic design  Durable and weather-resistant  Worry-free relaxation  Dimensions: 31.9" L x 31.5" W x 38" H  Seat height is 15.4 in. for a deep bucket seat and tall backrest  Chair Weighs 22 lbs. - heavy enough to not blow over in the wind, yet light enough to easily rearrange your patio space  350 lbs. capacity '

]

绕过机器人检测

虽然初看之下抓取沃尔玛似乎很简单,但随着项目规模的扩大,这个过程会变得越来越复杂和具有挑战性。该零售网站采用了多种技术来检测和阻止自动化流量,因此你的大规模抓取工具开始遭到封锁。

沃尔玛采用由 PerimeterX 提供的“按住不放”型 CAPTCHA,这种验证码几乎无法通过代码破解。此外,该网站还采用了 Akamai 和 ThreatMetrix 提供的防护措施,并收集多种浏览器数据来生成并关联您的唯一指纹。

在收集的浏览器数据中,我们发现:

  • Navigator对象的属性(deviceMemory、hardwareConcurrency、languages、platform、userAgent、webdriver等)
  • Canvas指纹识别
  • 时序与性能检测
  • 插件和语音枚举
  • Web Worker
  • 屏幕尺寸检测
  • 等等

要克服这些挑战并继续进行大规模抓取,一种方法是使用抓取 API。此类服务提供了一种简单可靠的方式,可从 walmart.com 等网站获取数据,而无需自行构建和维护抓取工具。

WebScrapingAPI 便是此类产品的典型代表。其代理轮换机制能彻底规避验证码,而扩展的知识库则可随机化浏览器数据,使其行为与真实用户无异。

配置过程快速简便。您只需注册一个账户,即可获得 API 密钥。该密钥可在控制面板中获取,并用于验证您发送的请求。

WebScrapingAPI dashboard welcome screen showing a three-step quickstart guide with API key, API playground, and documentation links

既然您已经配置好了 Node.js 环境,我们就可以使用相应的 SDK。运行以下命令将其添加到项目依赖项中:

npm install webscrapingapi

现在只需将之前的 CSS 选择器适配到 API 即可。强大的数据提取规则功能使您无需进行重大修改即可解析数据。

import webScrapingApiClient from 'webscrapingapi';

const client = new webScrapingApiClient("YOUR_API_KEY");

async function exampleUsage() {

    const api_params = {

        'render_js': 1,

    	  'proxy_type': 'residential',

    	  'timeout': 60000,

    	  'extract_rules': JSON.stringify({

            name: {

                selector: 'h1[itemprop="name"]',

                output: 'text',

        	},

        	rating: {

                selector: 'span[class$="rating-number"]',

                output: 'text',

        	},

        	reviews: {

                selector: 'a[itemprop="ratingCount"]',

                output: 'text',

        	},

        	price: {

                selector: 'span[itemprop="price"]',

                output: 'text',

        	},

        	images: {

                selector: 'div[data-testid="media-thumbnail"] > img',

                output: '@src',

                all: '1'

        	},

        	details: {

                selector: 'div.dangerous-html',

                output: 'text',

                all: '1'

        	}

        })

    }

    const URL = "https://www.walmart.com/ip/Keter-Adirondack-Chair-Resin-Outdoor-Furniture-Teal/673656371"

    const response = await client.get(URL, api_params)

    if (response.success) {

        console.log(response.response.data)

    } else {

        console.log(response.error.response.data)

    }

}

exampleUsage();

结论

本文为您概述了如何使用 TypeScript 和 Puppeteer 抓取沃尔玛网站数据。我们探讨了必要环境的搭建、数据识别与提取的过程,并提供了代码片段和示例以指导您完成整个流程。

抓取沃尔玛数据的优势包括:深入了解消费者行为、市场趋势、价格监控等诸多方面。

此外,选择专业的爬取服务可能是更高效的解决方案,因为它能确保流程完全自动化,并能应对可能遇到的机器人检测机制。

通过利用沃尔玛数据的强大价值,您可以推动业务取得成功,并在竞争中保持领先地位。请务必遵守网站的服务条款,避免过度抓取,以免被封禁。

关于作者
Raluca Penciuc, 全栈开发工程师 @ WebScrapingAPI
Raluca Penciuc全栈开发工程师

Raluca Penciuc 是 WebScrapingAPI 的全栈开发工程师,主要负责开发爬虫、优化规避机制,并探索可靠的方法以降低在目标网站上的被检测概率。

开始构建

准备好扩展您的数据收集规模了吗?

加入2,000多家企业,使用WebScrapingAPI在无需任何基础设施开销的情况下,以企业级规模提取网络数据。