如何批量获取M&S商品GraphQL评论并转为表格格式?
解决M&S GraphQL评论批量抓取与表格转换问题
问题背景
需要抓取M&S商品的全部评论,但GraphQL接口limit最大只能设为20,无法一次性获取(部分商品评论超1000条),同时要把返回的JSON评论转换成表格格式。
一、批量获取所有评论
利用接口返回的totalItems(总评论数),通过循环修改offset参数实现分页请求,逐步获取所有评论。
修改后的代码如下:
import json import requests import pandas as pd # 定义GraphQL查询语句(精简了不需要的字段,提升请求效率) query = """ query GetReviewsV2($id: String!, $sortBy: ReviewsSortBy!, $sortOrder: ReviewsSortOrder!, $limit: PositiveInt!, $offset: NonNegativeInt!, $filter: ReviewsFilter) { reviewsByProductId( filterAndSortInput: {sortBy: $sortBy, sortOrder: $sortOrder, filter: $filter} id: $id locale: GB paginationInput: {limit: $limit, offset: $offset} ) { ... on ReviewsSuccessResponse { controls { totalItems } reviews { id userNickname title submissionTime rating reviewText positiveFeedbackCount negativeFeedbackCount secondaryRatings { id value } } } } } """ def fetch_all_reviews(product_id): all_reviews = [] limit = 20 offset = 0 total_items = None while True: json_data = { 'query': query, 'variables': { 'id': product_id, 'sortBy': 'SUBMISSION_TIME', 'sortOrder': 'DESC', 'limit': limit, 'offset': offset, }, 'operationName': 'GetReviewsV2', } try: response = requests.post('https://prod.prod.gql-mesh.gql.mnscorp.net/graphql', json=json_data) response.raise_for_status() # 检查请求是否成功 data = response.json()['data']['reviewsByProductId'] # 第一次请求获取总评论数 if total_items is None: total_items = data['controls']['totalItems'] print(f"商品{product_id}共有{total_items}条评论,开始分批获取...") # 添加当前页评论到列表 all_reviews.extend(data['reviews']) print(f"已获取{len(all_reviews)}/{total_items}条评论") # 判断是否已获取全部 offset += limit if offset >= total_items: break except Exception as e: print(f"请求失败: {e}") break return all_reviews # 调用函数获取指定商品的所有评论 product_reviews = fetch_all_reviews('P60585886')
二、将评论转换为表格格式
把获取到的评论列表整理成结构化数据,提取关键字段(包括次级评分如Quality、Value),用pandas生成表格,可直接输出Markdown格式或保存为CSV文件。
添加以下代码:
def reviews_to_table(reviews): # 整理每条评论的数据 table_data = [] for review in reviews: # 提取次级评分(Quality、Value) secondary_ratings = {item['id']: item['value'] for item in review.get('secondaryRatings', [])} row = { '评论ID': review['id'], '用户名': review.get('userNickname', '匿名'), '评论标题': review.get('title', ''), '提交时间': review['submissionTime'], '总体评分': review['rating'], 'Quality评分': secondary_ratings.get('Quality', None), 'Value评分': secondary_ratings.get('Value', None), '评论内容': review.get('reviewText', ''), '点赞数': review['positiveFeedbackCount'], '点踩数': review['negativeFeedbackCount'] } table_data.append(row) # 转换为DataFrame df = pd.DataFrame(table_data) return df # 生成表格 reviews_df = reviews_to_table(product_reviews) # 输出Markdown格式表格 print(reviews_df.to_markdown(index=False)) # 保存为CSV文件(可选) reviews_df.to_csv('m&s_product_reviews.csv', index=False, encoding='utf-8-sig')
注意事项
- 控制请求间隔:如果评论数量较多,建议在循环中加入
time.sleep(1),避免频繁请求触发反爬机制 - 处理异常:代码中加入了基础的异常捕获,可根据需要扩展重试逻辑
- 字段适配:部分评论可能缺失次级评分或用户名,代码中已用
get方法处理空值
内容的提问来源于stack exchange,提问作者Rams
相关产品推荐
相关产品推荐

