Python+Beautiful Soup爬取仅获首页评论,求助全量评论及完整日期
玛莎百货商品评论爬取问题解决方案
一、解决翻页无URL变化,获取全部900条评论
页面翻页时URL不变,说明评论是通过AJAX异步加载的(点击翻页/滚动时后台请求API返回数据,不刷新页面),静态爬取Beautiful Soup无法获取后续页内容,需直接抓取评论API接口:
抓包获取评论API
- 打开浏览器开发者工具(F12),切换到「Network」标签,筛选「XHR/Fetch」类型;
- 点击页面的「下一页」或滚动加载更多评论,观察新出现的请求,找到返回评论数据的API地址;
- 记录API的请求参数(如
productId、page、pageSize、offset等)和请求头(User-Agent、Referer等,避免被反爬)。
循环请求API获取所有评论
根据总评论数和每页条数计算总页数,循环请求每一页的API数据,示例代码:import requests import json # 替换为你的商品ID和实际API地址 product_id = "YOUR_PRODUCT_ID" total_reviews = 900 page_size = 20 # 按实际每页显示条数调整 total_pages = (total_reviews // page_size) + 1 all_reviews = [] headers = { "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/118.0.0.0 Safari/537.36", "Referer": "https://www.marksandspencer.com/your-product-detail-url" } for page in range(1, total_pages + 1): api_url = f"https://api.marksandspencer.com/reviews/{product_id}?page={page}&pageSize={page_size}" resp = requests.get(api_url, headers=headers) if resp.status_code == 200: data = resp.json() # 按实际API返回的字段路径提取评论 for review in data.get("reviews", []): all_reviews.append({ "content": review.get("reviewText"), "full_date": review.get("submissionDate") # API返回的完整日期字段 }) else: print(f"第{page}页请求失败,状态码: {resp.status_code}") # 保存结果到文件 with open("m&s_reviews.json", "w", encoding="utf-8") as f: json.dump(all_reviews, f, ensure_ascii=False, indent=2)
二、提取完整评论发布日期
页面显示的年月只是格式化后的文本,完整日期通常藏在以下两个地方:
API返回的JSON数据中
绝大多数情况下,评论API会直接返回完整的日期(如2023-10-05T14:30:00Z格式),直接提取对应字段即可(如示例代码中的submissionDate)。静态HTML元素的属性中
如果是静态页面加载的评论,完整日期可能存放在元素的自定义属性里(如data-date、datetime),示例提取代码:from bs4 import BeautifulSoup # 假设已获取页面HTML内容 soup = BeautifulSoup(page_html, "html.parser") review_items = soup.find_all("div", class_="review-item") for item in review_items: # 替换为实际的日期元素选择器和属性名 date_elem = item.find("span", class_="review-date") full_date = date_elem.get("data-full-date") # 提取自定义属性中的完整日期 print(f"完整日期: {full_date}, 评论内容: {item.find('p', class_='review-text').text.strip()}")
注意事项
- 必须携带正确的请求头(尤其是
User-Agent和Referer),否则可能被服务器拦截; - 若遇到反爬限制,可添加请求延时(
time.sleep(1))或使用代理IP; - 验证API返回的总评论数是否与页面显示一致,避免循环超出实际页数。
内容的提问来源于stack exchange,提问作者Rams
相关产品推荐
相关产品推荐

