Python爬虫抓取知乎时一直报MalformRequestException错误怎么办?

Headers = {
    'Cookie': '_xsrf=....; tgw_l7_route=...; q_c1=fa50f62d64a347e2b2219e99935d1b4c|1532941819000|1532941819000; _zap=d722d2c4-2d96-4e09-a147-74a2fa53894e; z_c0=2...', 
      "Content-Type": "application/json",
     'User-Agent': 'ZhihuHybrid com.zhihu.android/Futureve/5.21.2 Mozilla/5.0 (Linux; Android 5.1.1; SM-G925F Build/LMY48Z) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/39.0.0.0 Safari/537.36', 
    'accept': 'application/json, text/plain, */*'

}

responsText= requests.post(‘https://www.zhihu.com/api/v4/answers/425660092/voters’, { “type”:“up” },headers=Headers, timeout=8 ).text

一直出现:

{code:400,
message:"请求错误",
name:"MalformRequestException"}

问题是我在 fiddler 抓到的就是这样的,一模一样....

结果我加了一个:

x-app-za:OS=Android&Release=5.1.1&Model=SM-G925F&VersionName=5.21.2&VersionCode=764&Product=com.zhihu.android&Width=1080&Height=1920&Installer=%E5%BA%94%E7%94%A8%E5%AE%9D-%E5%B9%BF%E5%91%8A&DeviceType=AndroidPhone&Brand=samsung&OperatorType=46000

就可以了,问题是....我在 fiddler 抓到的完全不需要这个参数....


Python爬虫抓取知乎时一直报MalformRequestException错误怎么办?

16 回复

反爬虫了解一下


这个错误通常是因为请求头不完整或者格式有问题,知乎的反爬机制比较严格。你得确保User-Agent、Cookie等关键头部都正确设置了,特别是x-zse-96这个参数现在知乎用得很多。

给你个能跑的示例,重点看headers部分:

import requests
import json

def fetch_zhihu_question(question_id):
    url = f"https://www.zhihu.com/api/v4/questions/{question_id}/answers"
    
    headers = {
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36',
        'Accept': 'application/json, text/plain, */*',
        'Accept-Language': 'zh-CN,zh;q=0.9',
        'Accept-Encoding': 'gzip, deflate, br',
        'x-api-version': '3.0.91',
        'x-zse-93': '101_3_3.0',
        # 注意:x-zse-96需要动态生成,这里只是示例格式
        'x-zse-96': '2.0_此处需要实际计算值',
        'Referer': f'https://www.zhihu.com/question/{question_id}',
        'Cookie': '你的cookie',  # 需要替换实际cookie
        'Connection': 'keep-alive',
    }
    
    params = {
        'include': 'data[*].is_normal,content,voteup_count',
        'limit': 5,
        'offset': 0,
    }
    
    try:
        response = requests.get(url, headers=headers, params=params, timeout=10)
        response.raise_for_status()
        return response.json()
    except requests.exceptions.RequestException as e:
        print(f"请求失败: {e}")
        return None

# 使用示例
if __name__ == "__main__":
    data = fetch_zhihu_question("123456789")  # 替换实际问题ID
    if data:
        print(json.dumps(data, ensure_ascii=False, indent=2))

关键点:

  1. User-Agent要用常见的浏览器值
  2. Cookie必须从浏览器复制真实的登录cookie
  3. x-zse-96参数现在知乎要求这个,需要逆向JS计算,你可以用execjs库执行知乎的加密算法
  4. 加个Referer头会更像正常浏览器访问

如果还不行,可能是cookie过期了,重新登录复制一次。另外建议加上请求间隔,别太频繁。

一句话建议:检查请求头完整性,特别是x-zse-96和cookie。

#1 问题是所有参数全部一样啊,一个在模拟器里面,一个用脚本跑而已…知乎怎么反…

你好好查查你抓的包,肯定是要这个参数的

#3 …我查了很多遍了,不需要的,要是要的话我也不会来问了

知乎的反爬做的很好的,别太高估自己了

#5 …我不至于连 fiddler 都看不懂

是不是 user agent 里有 android,所以后台会强制检测 android 版本信息什么的参数?

“问题是我在 fiddler 抓到的就是这样的,一模一样…" 这句话我没懂,fiddler 是能成功抓取还是不能呢?

#7


我在 fiddler 抓正常的请求,成功接收。

我把所有 headers 都复制到代码里面,用 Python 跑,结果失败了,一直返回 MalformRequestException 错误。

我又加了个 x-app-za 的 header 就突然好了…

x-app-za 这种是自定义头吗

#10 是的

这是要脚本刷赞?

如果是,建议别费心了,知乎刷赞的被检测到的话,会退回的。

#12 …我在写个知乎爬虫

爬内容不应该是 GET 请求吗?你给的代码是是什么 POST voters 资源…

#14 因为我想要完成一个知乎爬虫的所有功能,比如获取赞同者,赞同,取消赞同等等所有操作

回到顶部