Flipkart 是印度最大的电商平台之一,其每个商品页面都包含驱动价格追踪、竞品监控和目录研究所需的结构化信息:商品名称、当前价格、星级评分、评价数量,以及规格和亮点列表。问题在于,Flipkart 在浏览器中渲染这些页面并对自动流量设有防护,因此普通 HTTP 请求返回的只是一个近乎空白的 shell,而非你所需要的字段。
本指南演示如何以可靠的方式用 Python 抓取 Flipkart 商品页面。你将构建一个小型可运行的爬虫,通过 Crawling API 获取渲染后的商品页面,用 BeautifulSoup 解析所需字段,并输出整洁的结构化记录。整个流程仅限于公开商品数据,结尾处的合法性章节并非走过场,请在大量抓取前认真阅读。
你将构建什么
一个 Python 脚本:接受一个公开的 Flipkart 商品 URL,通过 Crawling API 获取渲染后的 HTML,并提取商品的结构化记录。我们以单个商品页面作为示例,提取以下字段:
- 名称 商品标题,例如某款耳机型号及其关键规格。
- 价格 页面显示的当前售价。
- 评分 平均星级,例如"4.3"。
- 评价数量 该商品的评分或评价数量。
- 亮点 Flipkart 在页面顶部附近显示的关键规格要点列表。
为什么普通请求在 Flipkart 上会失败
如果用裸 HTTP 客户端请求 Flipkart 商品 URL,返回的响应会缺失大部分数据。有两个原因。第一,Flipkart 通过 JavaScript 在客户端构建大部分商品内容,因此初始 HTML 很薄,只有页面脚本执行后才会填充内容。第二,Flipkart 能迅速识别自动化流量:数据中心 IP 和不像真实浏览器的请求模式会被拦截,或者在到达完整商品详情之前就收到一个精简页面。
因此,一个可用的 Flipkart 爬虫在单次请求中需要两件事:一个实际渲染页面的浏览器,以及一个平台认为是真实访客的 IP。你可以自己搭建无头浏览器加上一个轮换住宅代理池,但将这两者整合并保持正常运行占了大部分工作量。Crawling API 将两者合并为一次调用:你把 URL 和 JavaScript token 一起发给它,它在受信任的 IP 后面渲染页面,并返回供你解析的完整 HTML。
Crawlbase 提供两种 token 类型。普通 token 获取静态 HTML;JavaScript(JS)token 会先在真实浏览器中渲染页面。Flipkart 的商品详情依赖客户端渲染,因此这里 JS token 是安全的默认选择。普通 token 可能返回一个较薄的页面,其中价格、评分或亮点缺失,而那样的页面没有什么可解析的。
前提条件
在编写任何代码之前,你需要准备好以下几项。都不会花太长时间。
基础 Python 知识。 你应该能够编写和运行 Python 脚本,并使用 pip 安装包。如果你是 Python 新手,官方 Python 文档和任何入门课程都能让你达到本教程所需的水平。
Python 3.8 或更高版本。 用 python --version 确认版本。如果没有,从 python.org 安装,或通过 Anaconda 等发行版安装。
Crawlbase 账号和 JS token。 注册后打开控制台,复制你的 JavaScript(JS)token。请像对待密码一样保管 token:它用于验证你的请求,不要放入版本控制。
搭建项目
创建虚拟环境以隔离项目依赖,然后安装爬虫所需的两个库。
python --version python -m venv flipkart_env source flipkart_env/bin/activate pip install crawlbase beautifulsoup4
在 Windows 上,用 flipkart_env\Scripts\activate 替换 source 那行来激活环境。两个依赖各司其职:crawlbase 是 Crawling API 的官方客户端,beautifulsoup4 解析返回的 HTML,让你通过 CSS 选择器提取各个字段。如果你不熟悉 BeautifulSoup,BeautifulSoup 指南涵盖了本教程所依赖的基础知识。
第一步:获取渲染后的商品页面
先获取完整页面。导入 CrawlingAPI 类,用你的 JS token 初始化它,然后请求商品 URL。在解析之前检查状态码,可以让失败信息清晰可见,而不是悄无声息。
from crawlbase import CrawlingAPI api = CrawlingAPI({"token": "YOUR_CRAWLBASE_JS_TOKEN"}) def crawl(page_url): options = {"ajax_wait": "true", "page_wait": 5000} response = api.get(page_url, options) if response["status_code"] == 200: return response["body"].decode("utf-8") print(f"Request failed: {response['status_code']}") return None if __name__ == "__main__": page_url = "https://www.flipkart.com/oneplus-bullets-wireless-z2-bluetooth-headset/p/itm4c3852314bb61" html = crawl(page_url) print(html[:500] if html else "No HTML returned")
两个等待选项对这类客户端渲染目标非常重要。ajax_wait 告诉 API 等待异步内容加载完成,page_wait 在加载后再等待固定毫秒数,让延迟渲染的元素在页面被捕获前出现。5 秒是一个合理的起点;如果商品字段仍为空,可以增大该值。用 python scraper.py 运行脚本,你应该能看到真实的商品标记,而不是薄薄的 shell。这能在你编写第一个选择器之前确认渲染正常工作。
Flipkart 需要在受信任 IP 后面渲染页面,通过一次调用完成。Crawling API 接受 JS token,在真实浏览器中运行页面,在服务器端轮换住宅 IP,并将完整 HTML 交给你,省去了自己运行无头浏览器队列和代理池的麻烦。先用免费套餐指向一个公开商品页面试试。
第二步:用 BeautifulSoup 解析商品字段
拿到渲染后的 HTML,将其加载到 BeautifulSoup 并通过选择器提取每个字段。Flipkart 商品页面的核心详情布局具有可预测的结构,你可以将名称、价格、评分、评价数量和亮点列表映射到各自的选择器。将提取逻辑封装在辅助函数中,在字段缺失时返回 None,这样单个字段缺失不会导致整个运行崩溃。
from bs4 import BeautifulSoup import re def text_of(soup, selector): el = soup.select_one(selector) return el.get_text(strip=True) if el else None def scrape_product(html): soup = BeautifulSoup(html, "html.parser") price = text_of(soup, "div._30jeq3.x_zBx4") highlights = [ li.get_text(strip=True) for li in soup.select("div._7eSDEz li._21Ahn-") ] return { "name": text_of(soup, "span.B_NuCI"), "price": re.sub(r"\D", "", price) if price else None, "rating": text_of(soup, "div._3LWZlK"), "review_count": text_of(soup, "span._2_R_DZ"), "highlights": highlights, }
text_of 辅助函数同时完成两件事:查询单个元素,并在元素缺失时返回 None,而不是对空对象调用 .get_text() 抛出异常。这让提取在某个字段缺失时保持健壮,这种情况很常见,因为并非每件商品都有评分或完整的亮点块。价格经过一个小正则表达式处理,去除货币符号和逗号,留下可转换为数字的纯整数字符串。
Flipkart 的类名(如 _30jeq3、B_NuCI 和 _3LWZlK 这些哈希 token)是构建产物,会不定期变化。请将上述选择器视为起始模板,而非固定合约。当某个字段返回 None 时,在浏览器开发者工具中重新检查实时页面并更新选择器。定期维护选择器是任何生产爬虫的正常工作,并非哪里出错了的信号。
第三步:整合代码
现在将获取和解析整合为一个可运行的脚本。获取渲染后的 HTML,交给解析器,然后打印结构化记录。
import json import re from crawlbase import CrawlingAPI from bs4 import BeautifulSoup api = CrawlingAPI({"token": "YOUR_CRAWLBASE_JS_TOKEN"}) def crawl(page_url): options = {"ajax_wait": "true", "page_wait": 5000} response = api.get(page_url, options) if response["status_code"] == 200: return response["body"].decode("utf-8") print(f"Request failed: {response['status_code']}") return None def text_of(soup, selector): el = soup.select_one(selector) return el.get_text(strip=True) if el else None def scrape_product(html): soup = BeautifulSoup(html, "html.parser") price = text_of(soup, "div._30jeq3.x_zBx4") highlights = [ li.get_text(strip=True) for li in soup.select("div._7eSDEz li._21Ahn-") ] return { "name": text_of(soup, "span.B_NuCI"), "price": re.sub(r"\D", "", price) if price else None, "rating": text_of(soup, "div._3LWZlK"), "review_count": text_of(soup, "span._2_R_DZ"), "highlights": highlights, } def main(): page_url = "https://www.flipkart.com/oneplus-bullets-wireless-z2-bluetooth-headset/p/itm4c3852314bb61" html = crawl(page_url) if not html: return data = scrape_product(html) print(json.dumps(data, indent=2)) if __name__ == "__main__": main()
输出示例
用 python scraper.py 运行完整脚本,你会得到该商品的整洁结构化记录,可直接写入 JSON、CSV 或数据库。
{ "name": "OnePlus Bullets Wireless Z2 Bluetooth Headset", "price": "1799", "rating": "4.3", "review_count": "9,05,873 Ratings & 47,210 Reviews", "highlights": [ "30 Hrs Battery Life", "Fast Charge: 10 min for 20 hours", "Bluetooth version: 5.0" ] }
扩展到多个商品
单个商品只是演示;实际任务需要处理商品列表。结构保持不变:维护一个商品 URL 列表,通过 Crawling API 逐一获取,用同一个函数解析,然后收集结果。由于每个商品页面共享相同的结构,你已经写好的解析器无需修改即可适用所有页面。
import time product_urls = [ "https://www.flipkart.com/oneplus-bullets-wireless-z2-bluetooth-headset/p/itm4c3852314bb61", "https://www.flipkart.com/boat-airdopes-161-bluetooth-headset/p/itm8a7493150ae4a", ] results = [] for url in product_urls: html = crawl(url) if html: results.append(scrape_product(html)) time.sleep(2) with open("products.json", "w") as f: json.dump(results, f, indent=2)
要大规模构建 URL 列表,可以用同样的获取+解析模式抓取 Flipkart 公开搜索页面,收集商品链接后再逐一访问。每次请求之间的 time.sleep(2) 是有意为之的节奏控制:它防止你在紧密循环中频繁请求站点,而这是最快被限速的方式。更广泛的电商抓取策略,请参阅电商网络抓取指南。
保持不被封锁
即使渲染已处理妥当,Flipkart 仍会监测爬虫特征的流量。养成几个好习惯能让运行保持健康,这些习惯同样适用于任何强防护的商业目标。
- 控制请求频率。 在紧密循环中频繁请求页面是最快被限速的方式。分散请求并变换目标,而不是以全速爬取一条路径。
- 依赖 IP 轮换。 住宅 IP 池将请求分散到众多真实用户地址,使单个 IP 不会触发速率限制。Crawling API 为你处理这一切;如果你自己搭建,这部分是关键。
- 关注状态码。 运行期间开始返回挑战或错误,说明当前频率或 IP 层级已不够用。将其视为需要减速的信号,而不是可以忽略的噪音。
更广泛的策略请参阅如何在不被封锁的情况下抓取网站以及如何爬取 JavaScript 网站的深度剖析。如果你更倾向于通过轮换池路由自己的流量而非使用托管 API,Smart AI Proxy(也称 AI Proxy)以直连代理端点的形式提供同等的住宅 IP 轮换能力。
抓取 Flipkart 合法吗?
抓取 Flipkart 是否被允许,取决于 Flipkart 的服务条款、你所在的司法管辖区以及数据的用途。Flipkart 条款限制自动化访问,因此无论你的工具有多谨慎,抓取行为都可能违反这些条款。这里的代码不改变这一点,只是让技术部分得以运行。请阅读 Flipkart 使用条款及其 robots.txt,并将两者视为你采集内容的边界。
几条值得遵守的底线。只采集公开商品数据:任何人无需账号即可看到的商品名称、价格、评分、评价数量和亮点。尊重 Flipkart 声明的速率预期,保持请求量足够低,不给其服务器造成压力。避免涉及可识别个人的任何信息,包括评论者档案或公开汇总数量之外的买家详情。如果你计划将数据用于商业目的,请获得许可或正式协议,而不是将沉默视为默许。
本指南有意将范围限定在公开商品详情页,因为这是让工作具有可辩护性的边界。本指南不涵盖任何需要登录的内容:你的账号或订单历史、卖家后台、需要登录的页面,或任何绕过身份验证的尝试。如果你的项目需要超出公开商品数据的内容,对于批量或商业用途,正确的途径是 Flipkart 官方 API 或数据协议,而不是更聪明的爬虫。仅限公开商品数据。
核心要点
- Flipkart 在客户端渲染商品详情。 普通请求返回薄薄的页面,因此必须先渲染再解析。
-
你需要同时具备渲染能力和受信任的 IP。 带 JS token 的 Crawling API 通过一次调用同时完成;
ajax_wait和page_wait控制等待内容的时长。 - BeautifulSoup 负责提取。 将名称、价格、评分、评价数量和亮点映射到当前选择器,并预期这些哈希类名会发生变化。
- 通过循环 URL 实现扩展。 同一个解析器适用于每个商品页面,因此实际任务只是一个链接列表加上合理的节奏控制。
- 坚守公开数据。 尊重 Flipkart 的服务条款和 robots.txt,对于批量或商业用途优先选择官方 API 或协议,绝不触碰账号、订单或需要登录的页面。
常见问题
为什么普通请求从 Flipkart 返回不到商品数据?
因为 Flipkart 通过 JavaScript 在客户端构建大部分商品详情。初始 HTML 很薄,只有页面脚本在浏览器中运行后才会填充内容,因此原始 HTTP 请求可能返回缺少价格、评分或亮点的页面。要获取真实数据,必须先渲染页面,这正是 Crawling API 的 JS token 为你处理的事情。
Flipkart 需要普通 token 还是 JS token?
使用 JS token。普通 token 获取静态 HTML,在 Flipkart 上这可能是一个较薄的页面,关键商品字段缺失。JS token 在交还 HTML 之前先在真实浏览器中渲染页面,因此当 BeautifulSoup 解析时,名称、价格、评分和亮点都已存在。
我的选择器返回 None。是什么变了?
几乎可以肯定是 Flipkart 的标记发生了变化。其类名是 _30jeq3 和 B_NuCI 这类哈希构建产物,会在不通知的情况下变化,因此上个月有效的选择器可能会失效。在浏览器开发者工具中重新检查实时商品页面并更新选择器。定期维护选择器是任何生产爬虫的正常工作。
如何同时抓取多个 Flipkart 商品?
维护一个商品 URL 列表并循环遍历,通过 Crawling API 获取每个商品并用同一函数解析。先抓取 Flipkart 公开搜索页面来构建该 URL 列表。在请求之间添加短暂延迟,避免频繁请求站点,最后将收集到的结果写入 JSON 或 CSV。
应该使用 Flipkart 官方 API 还是抓取网站?
如果你需要授权数据、大批量、有保障的结构或商业再使用权,官方 API 或数据协议是正确的工具,能让你处于 Flipkart 条款允许的范围内。本指南中的方法抓取公开商品页面,适合没有 API 访问权限的小型、公开数据研究,但你必须遵守服务条款、robots.txt 和速率限制。
如何避免在抓取 Flipkart 时被封锁?
保持每个 IP 的请求频率较低,变换目标而不是循环同一路径,并通过轮换住宅 IP 路由,使单个地址不会触发速率限制。Crawling API 为你管理轮换和受信任的 IP 池;如果你自己搭建,这部分是关键所在。关注状态码,当开始出现挑战时及时退让。
大规模爬取任何站点,无需与基础设施对抗。
Crawlbase 负责处理代理、指纹和 CAPTCHA,让你的团队专注于交付数据流水线,而非维护爬取管道。1,000 次请求免费,无需信用卡。
