无需Selenium爬取Quora及POST请求400报错问题求助
我是网络爬虫新手,想要爬取Quora上某问题的全部回答(示例链接:https://www.quora.com/Would-you-rather-get-4000-a-week-for-the-rest-of-your-life-or-3-000-000-right-now)。该网站通过Ajax滚动加载更多内容,目前用Selenium能爬全量内容但速度慢;用requests.post请求Ajax接口始终返回400 Bad Request,requests.get请求网页仅能获取2条回答,怀疑是请求方式或反爬机制导致,附上代码请求排查:
data = { "queryName": "QuestionAnswerPagedListQuery", "variables": { "qid": 1053272, "first": 9, "after": "3", "adsData": "{\"answer_intervals\": [], \"ads\": []}", }, "extensions": { "hash": "c22beefa56a7d64ed1e67d4079189d089784a757b3495886f24f738e13a9af59" } } headers = { "cookie": 'xxx', "Accept": "*/*", "Accept-Encoding": "gzip, deflate, br", "Accept-Language": "zh-CN,zh-TW;q=0.9,zh-HK;q=0.8,zh;q=0.7,en-US;q=0.6,en;q=0.5", "Connection": "keep-alive", "Content-Type": "application/json", "User-Agent": "xxx" } post_url = 'https://www.quora.com/graphql/gql_para_POST?q=QuestionAnswerPagedListQuery' response = requests.post(url=post_url,json=data,headers=headers,proxies = proxies) url = 'https://www.quora.com/What-is-the-best-weight-loss-diet' get_response = requests.get(url=url,headers=headers,proxies = proxies)
问题排查及修复方案
1. JSON格式语法错误
你的data字典中,variables下的adsData字段末尾多了一个逗号,违反JSON规范会导致服务器解析失败返回400。修复后的数据结构:
data = { "queryName": "QuestionAnswerPagedListQuery", "variables": { "qid": 1053272, "first": 9, "after": "3", "adsData": "{\"answer_intervals\": [], \"ads\": []}" # 移除末尾多余的逗号 }, "extensions": { "hash": "c22beefa56a7d64ed1e67d4079189d089784a757b3495886f24f738e13a9af59" } }
2. QID与目标问题不匹配
你提供的示例问题QID并非1053272,需确保qid参数和目标问题对应。获取正确QID的方法:
- 打开目标问题页面,查看网页源码,搜索关键词
qid获取对应数值; - 从浏览器开发者工具的网络请求中提取已验证的QID。
3. 反爬验证头缺失
Quora的GraphQL接口需要额外验证头,仅Cookie和User-Agent不足以通过验证:
- 添加
X-Quora-CSRF-Token头,该值可从网页的<meta name="csrf-token">标签或Cookie中的m-b字段提取; - 确保使用的Cookie是当前有效会话的,建议从登录后的浏览器中复制完整Cookie(包括所有会话相关字段);
- 检查代理IP是否被Quora拉黑,可尝试更换代理或暂时关闭代理请求。
4. 分页游标参数错误
after参数是分页游标标识,初始请求应设为null或空字符串,而非"3"。后续分页请求的after值需从上一次响应的data.question.answers.page_info.end_cursor字段中提取。
5. 请求URL有效性检查
确认GraphQL接口URL是否正确:部分情况下,接口URL可能无需附加?q=QuestionAnswerPagedListQuery参数,可直接请求https://www.quora.com/graphql/gql_para_POST,同时对照浏览器开发者工具中实际发送的请求URL进行核对。
内容的提问来源于stack exchange,提问作者Robin777

