引言:人工智能时代浏览器自动化和数据收集的新范式
随着生成性人工智能、人工智能代理和数据密集型应用程序的快速崛起,浏览器正在从传统的"用户互动工具"演变为智能系统的"数据执行引擎"。在这一新范式中,许多任务不再依赖单一的API端点,而是通过自动化的浏览器控制来处理复杂的页面交互、内容抓取、任务编排和上下文检索。
从电商网站的价格比较和地图截图到搜索引擎结果解析和社交媒体内容提取,浏览器正成为人工智能获取现实世界数据的重要接口。然而,现代网络结构的复杂性、强大的反机器人措施和高并发需求给传统解决方案(如本地Puppeteer/Playwright实例或代理轮换策略)带来了重大技术和操作挑战。
引入无爬虫抓取浏览器------一个专为大规模自动化构建的先进云端浏览器平台。它克服了关键技术障碍,如反抓取机制、指纹检测和代理维护。此外,它提供了云原生并发调度、人类行为模拟和结构化数据提取,使其成为下一代自动化系统和数据管道的重要基础设施组成部分。
本文探讨无爬虫抓取浏览器的核心能力及其在浏览器自动化和网络抓取中的实际应用。通过分析当前行业趋势和未来方向,我们旨在为开发者、产品构建者和数据团队提供全面且系统的指南。
一、背景:我们为什么需要无爬虫抓取浏览器?
1.1 浏览器自动化的演变
在人工智能驱动的自动化时代,浏览器不再仅仅是人机交互的工具------它们已成为获取结构化和非结构化数据的基本执行端点。在许多现实场景中,API要么不可用,要么受到限制,因此必须通过浏览器模拟人类行为进行数据收集、任务执行和信息提取。
常见用例包括:
- 电商网站上的价格比较:价格和库存数据通常以异步方式在浏览器中加载。
- 解析搜索引擎结果页面:内容必须通过滚动和点击页面元素完全加载。
- 多语言网站、遗留系统和内联网平台:通过API无法访问数据。
传统的抓取解决方案(例如,本地运行的Puppeteer/Playwright或代理轮换设置)通常在高并发下表现不佳,频繁遭到反机器人封锁,并且维护成本高。无爬虫抓取浏览器凭借其云原生部署和真实浏览器行为模拟,为开发者提供了一个高可用、可靠的浏览器自动化平台------为人工智能自动化系统和数据工作流提供了关键基础设施。
1.2 反机器人机制的挑战
与此同时,随着反机器人技术的发展,传统爬虫工具越来越多地被目标网站标记为机器人流量,导致IP被封和访问限制。常见的反抓取机制包括:
- 浏览器指纹识别:通过用户代理、画布渲染、TLS握手等检测异常访问模式。
- CAPTCHA验证:要求用户证明自己是人类。
- IP黑名单:阻止过于频繁访问的IP。
- 行为分析算法:检测不寻常的鼠标移动、滚动速度和交互逻辑。
无爬虫抓取浏览器通过精确的浏览器指纹定制、内置的CAPTCHA解决方案和灵活的代理支持,有效克服了这些挑战,成为下一代自动化工具的核心基础设施。
二、无爬虫的核心能力
无爬虫抓取浏览器提供强大的核心能力,向用户提供稳定、高效和可扩展的数据交互功能。以下是其主要功能模块和技术细节:
2.1 真实浏览器环境
无爬虫建立在Chromium引擎之上,提供一个完整的浏览器环境,能够模拟真实用户行为。主要功能包括:
- TLS指纹伪造:伪造TLS握手参数以绕过传统反机器人机制。
- 动态指纹混淆:调整用户代理、屏幕分辨率、时区等,使每个会话看起来非常人性化。
- 本地化支持:自定义语言、地区和时区设置,使与目标网站的交互更自然。
深度定制浏览器指纹
无爬虫提供全面的浏览器指纹定制,允许用户创建更"真实"的浏览环境:
- 用户代理控制:在浏览器 HTTP 请求中定义 User-Agent 字符串,包括浏览器引擎、版本和操作系统。
- 屏幕分辨率映射 :设置
screen.width
和screen.height
的返回值,以模拟常见的显示尺寸。 - 平台属性锁定 :在 JavaScript 中指定
navigator.platform
的返回值,以模拟操作系统类型。 - 本地化环境仿真:完全支持自定义本地化设置,影响内容渲染、时间格式和网站上的语言首选项检测。
2.2 基于云的部署和可扩展性
Scrapeless 完全部署在云端,并提供以下优势:
- 无需本地资源:减少硬件成本,提高部署灵活性。
- 全球分布的节点:支持大规模并发任务,克服地理限制。
- 高并发支持:支持从 50 到无限的并发会话------适合从小任务到复杂自动化工作流程的所有场景。
性能比较
与传统工具如 Selenium 和 Playwright 相比,Scrapeless 在高并发场景中表现优异。以下是一个简单的比较表:
特性 | Scrapeless | Selenium | Playwright |
---|---|---|---|
并发支持 | 无限制(企业级定制) | 有限 | 中等 |
指纹定制 | 先进 | 基本 | 中等 |
CAPTCHA 解决能力 | 内置(98% 成功率) 支持 reCAPTCHA、Cloudflare Turnstile/Challenge、AWS WAF、DataDome 等 | 外部依赖 | 外部依赖 |
同时,Scrapeless 在高并发场景中表现优于其他竞争产品。以下是从不同维度总结的能力:
特性 / 平台 | Scrapeless | Browserless | Browserbase | HyperBrowser | Bright Data | ZenRows | Steel.dev |
---|---|---|---|---|---|---|---|
部署方式 | 基于云的 | 基于云的 Puppeteer 容器 | 多浏览器云集群 | 基于云的无头浏览器平台 | 云部署 | 浏览器 API 接口 | 浏览器云集群 + 浏览器 API |
并发支持 | 50 到无限 | 3--50 | 3--50 | 1--250 | 根据计划最多可达无限 | 多达 100(商业计划) | 无官方数据 |
反检测能力 | 免费的 CAPTCHA 识别与绕过,支持 reCAPTCHA、Cloudflare Turnstile/Challenge、AWS WAF、DataDome 等 | CAPTCHA 绕过 | CAPTCHA 绕过 + 隐私模式 | CAPTCHA 绕过 + 隐私 + 会话管理 | CAPTCHA 绕过 + 指纹伪造 + 代理 | 自定义浏览器指纹 | 代理 + 指纹识别 |
浏览器运行成本 | 每小时 0.063 -- 0.090(包括免费 CAPTCHA 绕过) | 每小时 0.084 -- 0.15(按单位) | 每小时 0.10 -- 0.198(包括 2--5GB 免费代理) | 每月 30--100 | 每小时 ~$0.10 | 每小时 ~$0.09 | 每小时 0.05 -- 0.08 |
代理成本 | 每 GB 1.26 -- 1.80 | 每 GB $4.3 | 每 GB $10(超出免费配额) | 无官方数据 | 每 GB 9.5(标准);每 GB 12.5(优质域名) | 每 GB 2.8 -- 5.42 | 每 GB 3 -- 8.25 |
2.3 CAPTCHA 自动解决和事件监控机制
Scrapeless 提供先进的 CAPTCHA 解决方案,并通过 Chrome DevTools Protocol (CDP) 扩展一系列自定义功能,以增强浏览器自动化的可靠性。
CAPTCHA 解决能力
Scrapeless 可以自动处理主流 CAPTCHA 类型,包括:reCAPTCHA、Cloudflare Turnstile/Challenge、AWS WAF、DataDome 等等。
事件监控机制
Scrapeless 提供了三个核心事件用于监控 CAPTCHA 解决过程:
事件名称 | 描述 |
---|---|
Captcha.detected | 检测到 CAPTCHA |
Captcha.solveFinished | CAPTCHA 已解决 |
Captcha.solveFailed | CAPTCHA 解决失败 |
事件响应数据结构
字段 | 类型 | 描述 |
---|---|---|
type | 字符串 | CAPTCHA 类型(例如:recaptcha, turnstile) |
success | 布尔值 | 解决结果 |
message | 字符串 | 状态信息(例如:"NOT_DETECTED","SOLVE_FINISHED") |
token? | 字符串 | 成功时返回的令牌(可选) |
2.4 强大的代理支持
Scrapeless 提供一个灵活可控的代理集成系统,支持多种代理模式:
- 内置住宅代理:支持全球 195 个国家/地区的地理代理,开箱即用。
- 自定义代理(高级订阅):允许用户连接到他们自己的代理服务,该服务不包括在 Scrapeless 的代理计费中。
2.5 会话重放
会话重放是 Scrapeless 抓取浏览器最强大的功能之一。它允许您逐页重放会话,以检查执行的操作和网络请求。
3. 代码示例:Scrapeless 集成和使用
3.1 使用 Scrapeless 抓取浏览器
Puppeteer 示例
const puppeteer = require('puppeteer-core');
const connectionURL = 'wss://browser.scrapeless.com/browser?token=your-scrapeless-api-key&session_ttl=180&proxy_country=ANY';
(async () => {
const browser = await puppeteer.connect({browserWSEndpoint: connectionURL});
const page = await browser.newPage();
await page.goto('https://www.scrapeless.com');
console.log(await page.title());
await browser.close();
})();
Playwright 示例
const {chromium} = require('playwright-core');
const connectionURL = 'wss://browser.scrapeless.com/browser?token=your-scrapeless-api-key&session_ttl=180&proxy_country=ANY';
(async () => {
const browser = await chromium.connectOverCDP(connectionURL);
const page = await browser.newPage();
await page.goto('https://www.scrapeless.com');
console.log(await page.title());
await browser.close();
})();
3.2 Scrapeless 抓取浏览器指纹参数示例代码
以下是一个简单的示例代码,展示如何通过 Puppeteer 和 Playwright 集成 Scrapeless 的浏览器指纹自定义功能:
Puppeteer 示例
const puppeteer = require('puppeteer-core');
// 自定义浏览器指纹
const fingerprint = {
userAgent: 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/134.1.2.3 Safari/537.36',
platform: 'Windows',
screen: {
width: 1280, height: 1024
},
localization: {
languages: ['zh-HK', 'en-US', 'en'], timezone: 'Asia/Hong_Kong',
}
}
const query = new URLSearchParams({
token: 'APIKey', // 必需
session_ttl: 180,
proxy_country: 'ANY',
fingerprint: encodeURIComponent(JSON.stringify(fingerprint)),
});
const connectionURL = `wss://browser.scrapeless.com/browser?${query.toString()}`;
(async () => {
const browser = await puppeteer.connect({browserWSEndpoint: connectionURL});
const page = await browser.newPage();
await page.goto('https://www.scrapeless.com');
const info = await page.evaluate(() => {
return {
screen: {
width: screen.width,
height: screen.height,
},
userAgent: navigator.userAgent,
timeZone: Intl.DateTimeFormat().resolvedOptions().timeZone,
languages: navigator.languages
};
});
console.log(info);
await browser.close();
})();
Playwright 示例
const { chromium } = require('playwright-core');
// custom browser fingerprint
const fingerprint = {
userAgent: 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/134.1.2.3 Safari/537.36',
platform: 'Windows',
screen: {
width: 1280, height: 1024
},
localization: {
languages: ['zh-HK', 'en-US', 'en'], timezone: 'Asia/Hong_Kong',
}
}
const query = new URLSearchParams({
token: 'APIKey', // required
session_ttl: 180,
proxy_country: 'ANY',
fingerprint: encodeURIComponent(JSON.stringify(fingerprint)),
});
const connectionURL = `wss://browser.scrapeless.com/browser?${query.toString()}`;
(async () => {
const browser = await chromium.connectOverCDP(connectionURL);
const page = await browser.newPage();
await page.goto('https://www.scrapeless.com');
const info = await page.evaluate(() => {
return {
screen: {
width: screen.width,
height: screen.height,
},
userAgent: navigator.userAgent,
timeZone: Intl.DateTimeFormat().resolvedOptions().timeZone,
languages: navigator.languages
};
});
console.log(info);
await browser.close();
})();
3.3 CAPTCHA事件监控示例
以下是使用Scrapeless监控CAPTCHA事件的完整代码示例,展示如何实时监控CAPTCHA的解决状态:
// 监听CAPTCHA解决事件
const client = await page.createCDPSession();
client.on('Captcha.detected', (result) => {
console.log('检测到CAPTCHA:', result);
});
await new Promise((resolve, reject) => {
client.on('Captcha.solveFinished', (result) => {
if (result.success) resolve();
});
client.on('Captcha.solveFailed', () =>
reject(new Error('CAPTCHA解决失败'))
);
setTimeout(() =>
reject(new Error('CAPTCHA解决超时')),
5 * 60 * 1000
);
});
掌握Scrapeless Scraping Browser的核心功能和优势后,我们不仅可以更好地理解其在现代网页爬虫中的价值,还可以更有效地利用其性能优势。为了帮助开发人员更高效和安全地自动化和爬取网站,我们将探讨如何在特定用例中应用Scrapeless Scraping Browser,基于常见场景。
4. 使用Scrapeless Scraping Browser的自动化和网页爬虫最佳实践
法律免责声明和预防措施
本教程涵盖了流行的网页爬虫技术,用于教育目的。与公共服务器的互动需要谨慎和尊重,以下是一些应避免的事项:
- 不要以可能损害网站的速度进行爬取。
- 不要爬取不公开的数据。
- 不要存储受GDPR保护的欧盟公民的个人信息。
- 不要重新使用整个公共数据集,这在某些国家可能是非法的。
理解Cloudflare保护
- 什么是Cloudflare?
Cloudflare是一个集成了内容分发网络(CDN)、DNS加速和安全保护的云平台。网站使用Cloudflare来缓解分布式拒绝服务(DDoS)攻击(即由于多个访问请求导致网站离线),并确保使用它的网站始终在线。
以下是一个简单的示例,用于理解Cloudflare的工作原理:
当您访问启用Cloudflare的网站(例如example.com)时,您的请求首先到达Cloudflare的边缘服务器,而不是源服务器。Cloudflare将根据多条规则判断是否允许您的请求继续,例如:
- 是否可以直接返回缓存页面;
- 是否需要通过CAPTCHA测试;
- 是否会阻止您的请求;
- 请求是否会被转发到实际的网站服务器(源)。
如果您被识别为合法用户,Cloudflare将转发请求到源服务器并将内容返回给您。此机制极大增强了网站的安全性,但也为自动访问带来了重大挑战。
绕过Cloudflare是许多数据收集任务中的技术难题之一。接下来,我们将深入探讨为何绕过Cloudflare是困难的。
- 绕过Cloudflare保护的挑战
绕过Cloudflare并不容易,尤其是在启用高级反机器人特性(如机器人管理、托管挑战、Turnstile验证、JS挑战等)时。许多传统的爬虫工具(如Selenium和Puppeteer)在请求甚至未发出之前,就因明显的指纹特征或不自然的行为模拟而被检测和阻止。
虽然有一些专门设计用于绕过Cloudflare的开源工具(例如FlareSolverr, undetected-chromedriver),但这些工具通常寿命较短。一旦它们被广泛使用,Cloudflare会迅速更新其检测规则以阻止它们。这意味着,要以持续和稳定的方式绕过Cloudflare的保护机制,团队通常需要内部开发能力以及持续的资源投入以进行维护和更新。
以下是绕过Cloudflare保护的主要挑战:
-
严格的浏览器指纹识别:Cloudflare会检测请求中的指纹特征,例如用户代理、语言设置、屏幕分辨率、时区和Canvas/WebGL渲染。如果检测到异常的浏览器或自动化行为,它会阻止请求。
-
复杂的 JS 挑战机制:Cloudflare 动态生成 JavaScript 挑战(如 CAPTCHA、延迟重定向、逻辑计算等),而自动化脚本通常难以正确解析或执行这些复杂的逻辑。
-
行为分析系统:除了静态指纹外,Cloudflare 还分析用户行为轨迹,如鼠标移动、在页面上停留的时间、滚动动作等。这需要在模拟人类行为方面具备高精度。
-
速率和并发控制:高频率的访问很容易触发 Cloudflare 的速率限制和 IP 阻止策略。代理池和分布式调度必须高度优化。
-
不可见的服务器端验证:由于 Cloudflare 是一个边缘拦截器,许多真实请求在到达源服务器之前就被阻止,从而使传统的数据包捕获分析方法无效。
因此,成功绕过 Cloudflare 需要模拟真实的浏览器行为、动态执行 JavaScript、灵活配置指纹,使用高质量的代理和动态调度机制。
使用 Scrapeless 爬虫浏览器绕过 Idealista 的 Cloudflare 收集房地产数据
在本章中,我们将演示如何使用 Scrapeless 爬虫浏览器构建一个高效、稳定且抗反爬的自动化系统,从 Idealista 这一领先的欧洲房地产平台抓取房地产数据。Idealista 采用了多种保护机制,包括 Cloudflare、动态加载、IP 速率限制和用户行为识别,使其成为一个非常具有挑战性的目标平台。
我们将重点关注以下技术方面:
- 绕过 Cloudflare 验证页面
- 自定义指纹与模拟真实用户行为
- 使用会话重放
- 高并发抓取与多个代理池
- 成本优化
理解挑战:Idealista 的 Cloudflare 保护
Idealista 是南欧领先的在线房地产平台,提供数百万条各种类型房产的列表,包括住宅、公寓和合租房。鉴于其房产数据的高度商业价值,该平台实施了严格的反爬虫措施。
为了抵御自动化抓取,Idealista 部署了 Cloudflare------一种广泛使用的防机器人和安全保护系统,旨在防御恶意机器人、DDoS 攻击和数据滥用。Cloudflare 的反抓取机制主要由以下元素组成:
- 访问验证机制:包括 JS 挑战、浏览器完整性检查和 CAPTCHA 验证,以确定访客是否为真实用户。
- 行为分析:通过鼠标移动、点击模式和滚动速度等行为检测真实用户。
- HTTP 头分析:检查浏览器类型、语言设置和引荐数据,以核实差异。可疑头信息可能暴露伪装成自动化机器人的尝试。
- 指纹检测与阻止:通过浏览器指纹、TLS 指纹和头信息识别由自动化工具(如 Selenium 和 Puppeteer)生成的流量。
- 边缘节点过滤:请求首先进入 Cloudflare 的全球边缘网络,该网络评估请求的风险。只有被认为低风险的请求才会转发到 Idealista 的源服务器。
接下来,我们将详细解释如何使用 Scrapeless 爬虫浏览器绕过 Idealista 的 Cloudflare 保护并成功收集房地产数据。
使用 Scrapeless 爬虫浏览器绕过 Idealista 的 Cloudflare
前提条件
在开始之前,让我们确保我们拥有必要的工具:
-
Python:如果您尚未安装 Python,请下载最新版本并将其安装在您的系统上。
-
所需库:您需要安装几个 Python 库。打开终端或命令提示符并运行以下命令:
pip install requests beautifulsoup4 lxml selenium selenium-wire undetected-chromedriver
-
ChromeDriver :下载 ChromeDriver。确保选择与您安装的 Chrome 版本相匹配的版本。
-
Scrapeless 账户 :要绕过 Idealista 的机器人保护,您需要一个 Scrapeless 爬虫浏览器账户。您可以 在这里注册 并获得 2 美元的免费试用。
定位数据
我们的目标是提取 Idealista 上每个房产列表的详细信息。我们可以使用浏览器的开发者工具来了解网站的结构并识别需要定位的 HTML 元素。
右键单击页面上的任意位置,选择 检查 以查看页面源代码。
在这篇文章中,我们将重点介绍如何使用以下网址从马德里阿尔卡拉-德-海纳雷斯抓取物业列表:
https://www.idealista.com/venta-viviendas/alcala-de-henares-madrid/
我们希望从每个列表中提取以下数据点:
- 标题
- 价格
- 面积信息
- 房产描述
- 图片网址
下面您可以看到带注释的房产列表页面,显示每个房源信息的位置。
通过检查HTML源代码,我们可以识别每个数据点的CSS选择器。CSS选择器是用于选择HTML文档中元素的模式。
通过检查HTML源代码,我们发现每个房产列表都包含在带有类 item
的 <article>
标签内。在每个项目内:
- 标题位于带有类
item-link
的<a>
标签中。 - 价格位于带有类
item-price
的<span>
标签中。 - 其他数据点也是如此。
步骤1:使用ChromeDriver设置Selenium
首先,我们需要配置Selenium以使用ChromeDriver。首先设置chrome_options
并初始化ChromeDriver。
from seleniumwire import webdriver
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.chrome.options import Options
from bs4 import BeautifulSoup
import time
from datetime import datetime
import json
def listings(url):
chrome_options = Options()
chrome_options.add_argument("--headless")
s = Service("替换为您的ChromeDriver路径")
driver = webdriver.Chrome(service=s, chrome_options=chrome_options)
这段代码导入了必要的模块,包括用于高级浏览器交互的seleniumwire
和用于HTML解析的BeautifulSoup
。
我们定义了一个函数listings(url)
,并通过向chrome_options
添加--headless
参数来配置Chrome在无头模式下运行。然后,使用指定的服务路径初始化ChromeDriver。
步骤2:加载目标网址
接下来,我们加载目标网址并等待页面完全加载。
driver.get(url)
time.sleep(8) # 根据网站的加载时间进行调整
在这里,driver.get(url)
命令指示浏览器导航到指定URL。
我们使用time.sleep(8)
使脚本暂停8秒,确保网页完全加载。这个等待时间可以根据网站的加载速度进行调整。
步骤3:解析页面内容
页面加载完成后,我们使用BeautifulSoup解析其内容:
soup = BeautifulSoup(driver.page_source, "lxml")
driver.quit()
在这里,我们使用driver.page_source
获取加载页面的HTML内容,并使用lxml
解析器通过BeautifulSoup解析它。最后,我们调用driver.quit()
关闭浏览器实例并释放资源。
步骤4:从解析的HTML中提取数据
接下来,我们从解析的HTML中提取相关数据。
house_listings = soup.find_all("article", class_="item")
extracted_data = []
for listing in house_listings:
description_elem = listing.find("div", class_="item-description")
description_text = description_elem.get_text(strip=True) if description_elem else "nil"
item_details = listing.find_all("span", class_="item-detail")
bedrooms = item_details[0].get_text(strip=True) if len(item_details) > 0 else "nil"
area = item_details[1].get_text(strip=True) if len(item_details) > 1 else "nil"
image_urls = [img["src"] for img in listing.find_all("img") if img.get("src")]
first_image_url = image_urls[0] if image_urls else "nil"
listing_info = {
"标题": listing.find("a", class_="item-link").get("title", "nil"),
"价格": listing.find("span", class_="item-price").get_text(strip=True),
"卧室": bedrooms,
"面积": area,
"描述": description_text,
"图片网址": first_image_url,
}
extracted_data.append(listing_info)
在这里,我们查找所有匹配带有类名 item
的article
标签的元素,表示各个房产列表。对于每个列表,我们提取其标题、细节(如卧室数量和面积)以及图片网址。我们将这些细节存储在一个字典中,并将每个字典附加到名为extracted_data
的列表中。
步骤5:保存提取的数据
最后,我们将提取的数据保存到JSON文件中。
current_datetime = datetime.now().strftime("%Y%m%d%H%M%S")
json_filename = f"new_revised_data_{current_datetime}.json"
with open(json_filename, "w", encoding="utf-8") as json_file:
```json
json.dump(extracted_data, json_file, ensure_ascii=False, indent=2)
print(f"提取的数据已保存到 {json_filename}")
url = "https://www.idealista.com/venta-viviendas/alcala-de-henares-madrid/"
idealista_listings = listings(url)
这里是完整的代码:
from seleniumwire import webdriver
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.chrome.options import Options
from bs4 import BeautifulSoup
import time
from datetime import datetime
import json
def listings(url):
chrome_options = Options()
chrome_options.add_argument("--headless")
s = Service("替换为您的ChromeDriver路径")
driver = webdriver.Chrome(service=s, chrome_options=chrome_options)
driver.get(url)
time.sleep(8) # 根据网站的加载时间进行调整
soup = BeautifulSoup(driver.page_source, "lxml")
driver.quit()
house_listings = soup.find_all("article", class_="item")
extracted_data = []
for listing in house_listings:
description_elem = listing.find("div", class_="item-description")
description_text = description_elem.get_text(strip=True) if description_elem else "nil"
item_details = listing.find_all("span", class_="item-detail")
bedrooms = item_details[0].get_text(strip=True) if len(item_details) > 0 else "nil"
area = item_details[1].get_text(strip=True) if len(item_details) > 1 else "nil"
image_urls = [img["src"] for img in listing.find_all("img") if img.get("src")]
first_image_url = image_urls[0] if image_urls else "nil"
listing_info = {
"标题": listing.find("a", class_="item-link").get("title", "nil"),
"价格": listing.find("span", class_="item-price").get_text(strip=True),
"卧室": bedrooms,
"面积": area,
"描述": description_text,
"图片网址": first_image_url,
}
extracted_data.append(listing_info)
current_datetime = datetime.now().strftime("%Y%m%d%H%M%S")
json_filename = f"new_revised_data_{current_datetime}.json"
with open(json_filename, "w", encoding="utf-8") as json_file:
json.dump(extracted_data, json_file, ensure_ascii=False, indent=2)
print(f"提取的数据已保存到 {json_filename}")
url = "https://www.idealista.com/venta-viviendas/alcala-de-henares-madrid/"
idealista_listings = listings(url)
绕过机器人检测
如果您在本教程中至少运行过两次脚本,您可能已经注意到出现了一个 CAPTCHA 页面。
Cloudflare 挑战页面最初加载 cf-chl-bypass
脚本并执行 JavaScript 计算,这通常需要大约 5 秒。
Scrapeless 提供了一种简单可靠的方法来访问如 Idealista 等网站的数据,而无需构建和维护自己的抓取基础设施。Scrapeless 抓取浏览器是一种高并发自动化解决方案,专为人工智能打造。它是一种高性能、成本效益高、抗封锁的浏览器平台,旨在大规模数据抓取,并模拟高度人类化的行为。它可以实时处理 reCAPTCHA、Cloudflare Turnstile/Challenge、AWS WAF、DataDome 等,使其成为高效的网络抓取解决方案。
以下是使用 Scrapeless 绕过 Cloudflare 保护的步骤:
步骤 1:准备
1.1 创建项目文件夹
-
创建一个新的项目文件夹,例如
scrapeless-bypass
。 -
在终端中导航到该文件夹:
cd path/to/scrapeless-bypass
1.2 初始化 Node.js 项目
运行以下命令以创建 package.json 文件:
npm init -y
1.3 安装所需依赖项
安装 Puppeteer-core,允许远程连接到浏览器实例:
npm install puppeteer-core
如果您的系统上尚未安装 Puppeteer,则安装完整版本:
npm install puppeteer puppeteer-core
步骤 2:获取您的 Scrapeless API 密钥
2.1 在 Scrapeless 上注册
- 前往 Scrapeless 并创建一个帐户。
- 导航到 API 密钥管理 部分。
- 生成一个新的 API 密钥并复制它。

步骤 3:连接到 Scrapeless 无浏览器
3.1 获取 WebSocket 连接 URL
Scrapeless 提供 Puppeteer 使用 WebSocket 连接 URL 与云端浏览器进行交互。
格式为:
wss://browser.scrapeless.com/browser?token=APIKey&session_ttl=180&proxy_country=ANY
将 APIKey 替换为您的实际 Scrapeless API 密钥。
3.2 配置连接参数
token
:您的 Scrapeless API 密钥session_ttl
:浏览器会话持续时间(以秒为单位),例如180
proxy_country
:代理服务器的国家代码(例如,GB
表示英国,US
表示美国)
第4步:编写Puppeteer脚本
4.1 创建脚本文件
在您的项目文件夹中,创建一个名为bypass-cloudflare.js
的新JavaScript文件。
4.2 连接到Scrapeless并启动Puppeteer
将以下代码添加到bypass-cloudflare.js
中:
import puppeteer from 'puppeteer-core';
const API_KEY = 'your_api_key'; // 用实际API密钥替换
const host = 'wss://browser.scrapeless.com';
const query = new URLSearchParams({token: API_KEY, session_ttl: '180', // 浏览器会话持续时间(秒)proxy_country: 'GB', // 代理国家代码proxy_session_id: 'test_session', // 代理会话ID(保持相同IP)proxy_session_duration: '5' // 代理会话持续时间(分钟)
}).toString();
const connectionURL = `${host}/browser?${query}`;
const browser = await puppeteer.connect({browserWSEndpoint: connectionURL, defaultViewport: null,
});
console.log('连接到Scrapeless');
4.3 打开网页并绕过Cloudflare
扩展脚本以打开新页面并导航到Cloudflare保护的网站:
const page = await browser.newPage();
await page.goto('https://www.scrapingcourse.com/cloudflare-challenge', { waitUntil: 'domcontentloaded' });
4.4 等待页面元素加载
在继续之前确保绕过Cloudflare保护:
await page.waitForSelector('main.page-content .challenge-info', { timeout: 30000 }); // 根据需要调整选择器
4.5 截取屏幕截图
为验证Cloudflare保护是否已成功绕过,截取页面的屏幕截图:
await page.screenshot({ path: 'challenge-bypass.png' });
console.log('屏幕截图已保存为 challenge-bypass.png');
4.6 完整脚本
以下是完整脚本:
import puppeteer from 'puppeteer-core';
const API_KEY = 'your_api_key'; // 用实际API密钥替换
const host = 'wss://browser.scrapeless.com';
const query = new URLSearchParams({
token: API_KEY,
session_ttl: '180',
proxy_country: 'GB',
proxy_session_id: 'test_session',
proxy_session_duration: '5'
}).toString();
const connectionURL = `${host}/browser?${query}`;
(async () => {
try {
// 连接到Scrapeless
const browser = await puppeteer.connect({
browserWSEndpoint: connectionURL,
defaultViewport: null,
});
console.log('连接到Scrapeless');
// 打开新页面并导航到目标网站
const page = await browser.newPage();
await page.goto('https://www.scrapingcourse.com/cloudflare-challenge', { waitUntil: 'domcontentloaded' });
// 等待页面完全加载
await page.waitForTimeout(5000); // 如有必要可调整延迟
await page.waitForSelector('main.page-content', { timeout: 30000 });
// 截取屏幕截图
await page.screenshot({ path: 'challenge-bypass.png' });
console.log('屏幕截图已保存为 challenge-bypass.png');
// 关闭浏览器
await browser.close();
console.log('浏览器已关闭');
} catch (error) {
console.error('错误:', error);
}
})();
第5步:运行脚本
5.1 保存脚本
确保将脚本保存为bypass-cloudflare.js。
5.2 执行脚本
使用Node.js运行脚本:
node bypass-cloudflare.js
5.3 预期输出
如果一切设置正确,终端将显示:
连接到Scrapeless
屏幕截图已保存为 challenge-bypass.png
浏览器已关闭
challenge-bypass.png文件将出现在您的项目文件夹中,确认Cloudflare保护已成功绕过。
您还可以将Scrapeless抓取浏览器直接集成到您的抓取代码中:
const puppeteer = require('puppeteer-core');
const connectionURL = 'wss://browser.scrapeless.com/browser?token=C4778985476352D77C08ECB031AF0857&session_ttl=180&proxy_country=ANY';
(async () => {
const browser = await puppeteer.connect({browserWSEndpoint: connectionURL});
const page = await browser.newPage();
await page.goto('https://www.scrapeless.com');
console.log(await page.title());
await browser.close();
})();
指纹自定义
在抓取网站数据时------尤其是像Idealista 这样的大型房地产平台------即使您成功绕过了Cloudflare 挑战,通过Scrapeless,仍然可能由于重复或高频率的访问被标记为机器人。
网站通常使用浏览器指纹识别来检测自动化行为并限制访问。
⚠️ 常见问题
-
多次抓取后响应时间变慢
网站可能会根据IP或行为模式限制请求。
-
页面布局未能渲染
动态内容可能依赖于真实的浏览器环境,导致抓取期间数据缺失或破损。
-
某些地区缺少列表
网站可能会根据可疑的流量模式阻止或隐藏内容。
这些问题通常是由于每个请求的浏览器配置相同造成的。如果您的浏览器指纹保持不变,反机器人系统就容易检测到自动化。
解决方案:使用 Scrapeless 自定义指纹
Scrapeless 抓取浏览器 提供了内置的指纹自定义支持,以模拟真实用户行为并避免被检测。
您可以 随机化或自定义 以下指纹元素:
指纹元素 | 描述 |
---|---|
用户代理 | 模拟各种操作系统/浏览器组合(例如,Windows/Mac上的Chrome)。 |
平台 | 模拟不同的操作系统(Windows、macOS 等)。 |
屏幕大小 | 仿真各种设备分辨率,以避免移动/桌面不匹配。 |
本地化 | 与地理位置一致对齐语言和时区。 |
通过旋转或自定义这些值,每个请求看起来更自然------减少被检测的风险,提高数据提取的可靠性。
代码示例:
const puppeteer = require('puppeteer-core');
const query = new URLSearchParams({
token: 'your-scrapeless-api-key', // 必需
session_ttl: 180,
proxy_country: 'ANY',
// 设置指纹参数
userAgent: 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/134.0.6998.45 Safari/537.36',
platform: 'Windows',
screen: JSON.stringify({ width: 1280, height: 1024 }),
localization: JSON.stringify({
locale: 'zh-HK',
languages: ['zh-HK', 'en-US', 'en'],
timezone: 'Asia/Hong_Kong',
})
});
const connectionURL = `wss://browser.Scrapeless.com/browser?${query.toString()}`;
(async () => {
const browser = await puppeteer.connect({browserWSEndpoint: connectionURL});
const page = await browser.newPage();
await page.goto('https://www.Scrapeless.com');
console.log(await page.title());
await browser.close();
})();
会话重放
在自定义浏览器指纹后,页面稳定性显著提高,内容提取变得更加可靠。
然而,在大规模抓取操作期间,意外问题仍可能导致提取失败。为此,Scrapeless 提供了强大的 会话重放 功能。
什么是会话重放?
会话重放详细记录整个浏览器会话,捕捉所有交互,如:
- 页面加载过程
- 网络请求和响应数据
- JavaScript 执行行为
- 动态加载但未解析的内容
为什么使用会话重放?
在抓取复杂网站如 Idealista 时,会话重放可以大大提高调试效率。
益处 | 描述 |
---|---|
精确问题追踪 | 快速识别失败的请求,无需猜测 |
无需重新运行代码 | 直接从重放中分析问题,而不是重新运行抓取器 |
改善协作 | 与团队成员共享重放日志以便于故障排除 |
动态内容分析 | 理解在抓取过程中动态加载的数据如何表现 |
使用提示
一旦 会话重放 启用,抓取失败或数据看起来不完整时,首先检查重放日志。这有助于您更快地诊断问题,减少调试时间。
代理配置
在抓取 Idealista 时,重要的是要注意该平台对非本地 IP 地址高度敏感------尤其是在访问特定城市的列表时。如果您的 IP 来源于国外,Idealista 可能会:
- 完全阻止请求
- 返回简化或删减版本的页面
- 提供空或不完整的数据,即使没有触发 CAPTCHA
Scrapeless 内置代理支持
Scrapeless 提供 内置代理配置,允许您直接指定地理来源。
您可以通过以下任一方式进行配置:
proxy_country
:一个两字母国家代码(例如,西班牙为'ES'
)proxy_url
:您自己的代理服务器 URL
示例用法:
proxy_country: 'ES',
高并发
我们刚刚从 Idealista 抓取的页面------阿尔卡拉·德·埃纳雷斯房产列表------有多达 6 页的列表。
当您研究行业趋势或收集竞争营销策略时,可能需要每天从 20+ 个城市 抓取房地产数据,涵盖 数千个页面。在某些情况下,您甚至可能需要每小时刷新这些数据。

高并发要求
为高效处理这种容量,请考虑以下要求:
- 多个并发连接:无需长时间等待即可从数百个页面抓取数据。
- 自动化工具:使用Scrapeless Scraping Browser或类似工具,这些工具能够处理大规模的并发请求。
- 会话管理:保持持久会话,以避免过多的验证码或IP封锁。
无痛扩展性
Scrapeless专门为高并发抓取设计。它提供:
- 并行浏览器会话:同时处理多个请求,使您能够在多个城市快速抓取大量数据。
- 低成本、高效抓取:并行抓取降低了每页抓取的成本,同时优化了吞吐量。
- 绕过高流量反机器人防御:即使在高负荷抓取期间,也能自动处理验证码和其他验证系统。
提示:确保您的请求间隔合理,以模拟人类的浏览行为,防止Idealista的速率限制或封禁。
扩展性与成本效率
常规的Puppeteer在高效扩展会话和与排队系统集成方面表现不佳。然而,Scrapeless Scraping Browser支持从数十个 并发会话到无限 并发会话的无缝扩展,确保即使在高峰任务负载期间也零排队时间和零超时。
以下是各种高并发抓取工具的比较。即使使用Scrapeless的高并发浏览器,您也无需担心成本------实际上,它可以帮助您节省近**50%**的费用。
工具比较
工具名称 | 小时费率 (美元/小时) | 代理费用 (美元/GB) | 并发支持 |
---|---|---|---|
Scrapeless | 0.063 -- 0.090/小时 (取决于并发性和使用情况) | 1.26 -- 1.80/GB | 50 / 100 / 200 / 400 / 600 / 1000 / 无限制 |
Browserbase | 0.10 -- 0.198/小时 (包含2-5GB免费代理) | $10/GB(超出免费分配后) | 3(基础) / 50(高级) |
Brightdata | $0.10/小时 | 9.5/GB(标准);12.5/GB(高级域名) | 无限 |
Zenrows | $0.09/小时 | 2.8 -- 5.42/GB | 高达100 |
Browserless | 0.084 -- 0.15/小时 (基于使用单位计费) | $4.3/GB | 3 / 10 / 50 |
提示 :如果您需要大规模抓取 和高并发支持 ,Scrapeless提供最佳的性价比。
网络抓取的成本控制策略
细心的用户可能已经注意到,我们抓取的Idealista页面通常包含大量高清地产图片、互动地图、视频演示和广告脚本。尽管这些元素对最终用户友好,但对数据提取而言是不必要的,并显著增加了带宽消耗和成本。

为了优化流量使用,我们建议用户采用以下策略:
- 资源拦截:拦截不必要的资源请求以减少流量消耗。
- 请求URL拦截:根据URL特征拦截特定请求,以进一步减少流量。
- 模拟移动设备:使用移动设备配置来获取更轻的页面版本。
详细策略
1. 资源拦截
启用资源拦截可以显著提高抓取效率。通过配置Puppeteer的setRequestInterception
函数,我们可以阻止图像、媒体、字体和样式表等资源的加载,从而避免下载大量内容。
2. 请求URL过滤
通过检查请求URL,我们可以过滤掉与数据提取无关的无效请求,如广告服务和第三方分析脚本。这降低了不必要的网络流量。
3. 模拟移动设备
模拟移动设备(例如,将用户代理设置为iPhone)允许您获取更轻的、经过移动优化的页面版本。这会导致加载的资源更少,从而加快抓取过程。
要获取更多信息,请参考Scrapeless官方文档
示例代码
以下是使用Scrapeless Cloud Browser + Puppeteer的示例代码,展示如何结合这三种策略进行优化资源抓取:
import puppeteer from 'puppeteer-core';
const scrapelessUrl = 'wss://browser.scrapeless.com/browser?token=your_api_key&session_ttl=180&proxy_country=ANY';
async function scrapeWithResourceBlocking(url) {
const browser = await puppeteer.connect({
browserWSEndpoint: scrapelessUrl,
defaultViewport: null
});
const page = await browser.newPage();
// Enable request interception
await page.setRequestInterception(true);
// Define resource types to block
const BLOCKED_TYPES = new Set([
'image',
'font',
'media',
'stylesheet',
]);
// Intercept requests
page.on('request', (request) => {
if (BLOCKED_TYPES.has(request.resourceType())) {
request.abort();
console.log(`Blocked: ${request.resourceType()} - ${request.url().substring(0, 50)}...`);
} else {
request.continue();
}
});
await page.goto(url, {waitUntil: 'domcontentloaded'});
// Extract data
const data = await page.evaluate(() => {
return {
title: document.title,
content: document.body.innerText.substring(0, 1000)
};
});
await browser.close();
return data;
}
// Usage
scrapeWithResourceBlocking('https://www.scrapeless.com')
.then(data => console.log('Scraping result:', data))
.catch(error => console.error('Scraping failed:', error));
通过这种方式,您不仅可以节省高额的流量费用,还能在确保数据质量的同时提高爬取速度,从而改善系统的整体稳定性和效率。
5. 安全和合规建议
在使用Scrapeless进行数据爬取时,开发人员应注意以下事项:
- 遵守目标网站的
robots.txt
文件及相关法律法规:确保您的爬取活动是合法的,并尊重网站的指南。 - 避免过度请求,导致网站停机:注意爬取频率,以防止服务器过载。
- 不爬取敏感信息:不要收集用户隐私数据、支付信息或任何其他敏感内容。
6. 结论
在大数据时代,数据收集已成为各行业数字化转型的关键基础。尤其是在市场情报、电子商务价格比较、竞争分析、金融风险管理和房地产分析等领域,对数据驱动决策的需求愈加迫切。然而,随着网络技术的持续演变,特别是动态加载内容的广泛使用,传统网页爬虫逐渐显露出其局限性。这些局限性不仅使爬取变得更加困难,而且导致反爬机制的升级,提高了网页爬取的门槛。
随着网络技术的进步,传统爬虫已无法满足复杂爬取需求。以下是一些主要挑战及相应解决方案:
- 动态内容加载:基于浏览器的爬虫通过模拟真实浏览器对JavaScript内容的渲染,确保能够爬取动态加载的网页数据。
- 反爬机制:通过使用代理池、指纹识别、行为模拟等技术,我们可以绕过传统爬虫常触发的反爬机制。
- 高并发爬取:无头浏览器支持高并发任务部署,配合代理调度,以满足大规模数据爬取的需求。
- 合规问题:通过使用合法的API和代理服务,可以确保爬取活动遵循目标网站的条款。
因此,基于浏览器的爬虫已成为行业的新趋势。这项技术不仅通过真实浏览器模拟用户行为,还灵活应对现代网站的复杂结构和反爬机制,为开发人员提供更稳定和高效的爬取解决方案。
Scrapeless抓取浏览器顺应这一技术趋势,通过结合浏览器渲染、代理管理、反检测技术和高并发任务调度,帮助开发人员在复杂的在线环境中高效稳定地完成数据爬取任务。它通过几个核心优势提高爬取效率和稳定性:
-
高并发浏览器解决方案:Scrapeless支持大规模的高并发任务,能够快速部署数千个爬取任务,以满足长期爬取需求。
-
反检测即服务:内置的验证码解决器和可定制的指纹帮助开发人员绕过指纹和行为识别机制,大大降低被封禁的风险。
-
可视化调试工具 - 会话重放:通过回放爬取过程中的每次浏览器交互,开发人员可以轻松调试和诊断爬取过程中的问题,特别是处理复杂页面和动态加载内容时。
-
合规性和透明性保障 :Scrapeless强调合规的数据爬取,支持遵守网站的
robots.txt
规则,并提供详细的爬取日志,以确保用户的数据爬取活动符合目标网站的政策。 -
灵活的可扩展性:Scrapeless与Puppeteer无缝集成,使用户能够自定义其抓取策略,并与其他工具或平台连接,实现一站式的数据抓取和分析工作流程。
无论是抓取电子商务平台以进行价格比较,提取房地产网站数据,还是应用于金融风险监测和市场情报分析,Scrapeless为各种行业提供高效、智能和可靠的解决方案。
通过本文涵盖的技术细节和最佳实践,您现在了解如何利用Scrapeless进行大规模数据抓取。无论是处理动态页面、提取复杂的交互数据、优化流量使用,还是克服反抓取机制,Scrapeless都能帮助您快速高效地实现抓取目标。