使用Pandas导出Facebook评论时部分内容被错误解析为随机数字的问题
Pandas导出Facebook评论时部分内容被错误解析为随机数字的问题
嘿,我仔细看了你的问题和代码,碰到超过300条评论后部分内容变成随机数字的情况,大概率不是请求频率的问题(你加的10秒等待其实已经足够宽松了),更可能是Facebook API的特殊返回逻辑或者代码里的细节处理不到位导致的,我给你梳理下可能的原因和解决办法:
先搞清楚问题根源:API返回的原始数据是什么?
你现在直接把message转成字符串,但如果Facebook API对某些评论返回的message本身就是数字(比如用户删除评论后的占位ID、隐私受限的评论内容、或者系统自动生成的特殊标记),转成str后就会显示成“随机数字”。
第一步建议你先在代码里加个调试打印,看看那些出问题的评论原始数据长什么样:
for comment in data["data"]: # 加这行打印,直接看API返回的原始评论结构 print(f"调试:原始评论数据 → {comment}") comment_id = comment.get("id") # ... 后面的代码不变
跑一次后,你就能看到那些变成数字的评论,message字段到底是数字、空值还是其他内容,这样就能精准定位问题。
针对性的解决办法
1. 严谨处理message字段,避免直接转数字为字符串
如果发现某些评论的message是数字(比如API返回的是内部ID而不是实际内容),可以在代码里判断类型,替换成友好提示:
# 替换原来的comment_message赋值逻辑 raw_message = comment.get("message", "Nėra komentaro") # 如果是数字类型,说明不是实际评论内容 if isinstance(raw_message, (int, float)): comment_message = "Komentaro turimas yra neprieinamas" else: comment_message = str(raw_message)
2. 不要手动拼接分页URL,直接用API返回的next链接
你现在手动拼接after游标URL,可能会因为游标包含特殊字符、API版本兼容问题导致拉到错误数据。直接用paging里的next字段更可靠:
# 替换原来的分页逻辑 paging = data.get("paging", {}) # 直接用API返回的完整next URL,不用自己拼 url = paging.get("next") if url: time.sleep(10) else: url = None
3. 检查API权限和版本
Facebook Graph API v22.0对评论内容的获取有严格权限要求:
- 确保你的
ACCESS_TOKEN拥有pages_read_engagement权限(针对公共主页评论) - 如果你拉的是个人帖子评论,需要
user_posts权限
如果权限不足,API会返回部分内容的占位符(比如数字ID)而不是实际评论。
4. 加入错误处理,避免异常数据混入
API请求可能会因为网络、权限、速率限制等原因返回错误,你现在的代码没有处理这些情况,可能会把错误数据(比如包含error字段的JSON)当成正常评论处理:
# 在请求后加入错误检查 response = requests.get(url) # 先检查HTTP状态码 if response.status_code != 200: print(f"请求失败,状态码: {response.status_code},详情: {response.text}") time.sleep(15) # 出错后多等会儿再重试 continue data = response.json() # 检查API返回的错误信息 if "error" in data: print(f"API错误提示: {data['error']['message']}") # 如果是速率限制,多等一会儿 if data["error"].get("code") == 4: time.sleep(60) break
修改后的完整代码
import requests import json import time import pandas as pd ACCESS_TOKEN = "xx" POST_ID = "xx" # main function to get comments def get_all_comments(post_id, limit=1000): comments = [] url = f"https://graph.facebook.com/v22.0/{post_id}/comments?fields=id,message,from&limit=50&access_token={ACCESS_TOKEN}" while url: response = requests.get(url) # 检查HTTP请求状态 if response.status_code != 200: print(f"请求失败,状态码: {response.status_code},详情: {response.text}") time.sleep(15) continue data = response.json() # 检查API返回错误 if "error" in data: print(f"API错误: {data['error']['message']}") if data["error"].get("code") == 4: # 速率限制 time.sleep(60) break if "data" in data: for comment in data["data"]: # 调试用:打印原始评论数据,排查问题时打开 # print(f"调试:原始评论 → {comment}") comment_id = comment.get("id") commenter_name = comment.get("from", {}).get("name", "Nežinomas komentuotojas") # 严谨处理message字段 raw_message = comment.get("message", "Nėra komentaro") if isinstance(raw_message, (int, float)): comment_message = "Komentaro turimas yra neprieinamas" else: comment_message = str(raw_message) comments.append({"Vartotojas": commenter_name, "Komentaras": comment_message}) # Stopping when gets the amount of comments equal to limits if len(comments) >= limit: return comments paging = data.get("paging", {}) # 直接使用API返回的next URL url = paging.get("next") if url: time.sleep(10) return comments comments = get_all_comments(POST_ID, limit=1000) # Saving in JSON with open("comments_from_page.json", "w", encoding="utf-8") as file: json.dump(comments, file, ensure_ascii=False, indent=4) print(f" Iš viso gauta {len(comments)} komentarų.") # Saving in excel df = pd.DataFrame(comments) df.to_excel("comments_from_page.xlsx", index=False, engine='openpyxl') print("Komentarai sėkmingai perkelti į 'comments_from_page.xlsx'.")
最后总结
- 先通过调试打印确认出问题的评论原始数据,确定是API返回的占位符还是代码处理问题
- 优先用API提供的
next分页链接,不要手动拼接 - 对
message字段做类型判断,避免把数字ID当成评论内容 - 加入错误处理,避免异常数据混入结果
备注:内容来源于stack exchange,提问作者Citelis




