Python爬虫实战:利用requests构建知乎私信API

小满
小满
发布时间:2026-10-14 | 3人浏览过
原创

本文基于Python的requests库,详细解析如何构建知乎私信发送API。通过抓包分析HTTP请求头、URL及JSON请求体,获取用户ID与认证信息,实现登录状态下的私信发送功能。教程涵盖从网络请求追踪到代码实现的完整流程,提供获取用户信息、构造请求及调用API的关键代码示例,帮助开发者掌握利用requests模拟浏览器操作的核心技巧。

前言

前言

在之前的爬虫系列文章《优雅的HTTP库requests》中,我们介绍了requests的基本用法。本文将进一步深入,利用requests构建一个知乎API接口,实现私信发送、文章点赞以及用户关注等功能。由于这些涉及用户交互的操作均需要登录状态,建议读者在阅读本文前,先掌握Python模拟知乎登录的方法。假设您已具备通过requests模拟登录知乎的基础知识。

思路分析

思路分析

发送私信的本质是浏览器向服务器发起HTTP请求。该请求包含请求URL、请求头(Header)以及请求体(Body)。只要明确这些要素,即可使用requests轻松模拟浏览器发送私信。

打开Chrome浏览器,随机选择一位用户并点击“发送私信”,通过开发者工具追踪私信发送过程中的网络请求。

首先查看请求头信息。

请求头Header中包含了登录所需的cookies信息,此外还有一个authorization字段,用于用户身份认证。该字段同样存在于cookies中(为保护隐私,原文对此打了马赛克)。在使用requests发起请求时,必须携带这些信息以确保请求合法。

接下来分析请求的URL和请求体。

请求URL为 https://www.zhihu.com/api/v4/messages ,请求方法为POST,请求体如下所示:


{"type":"common","content":"你好,我是pythoner","receiver_hash":"1da75b85900e00adb072e91c56fd9149"}

请求体是一个JSON字符串。其中type和content字段含义明确,但receiver_hash的具体含义尚不明确,需要进一步确认。不过可以推测,这类似于用户ID的字段。

接下来需要解决的核心问题是:如何通过用户主页URL获取用户ID?为了完整模拟私信发送流程,我专门注册了一个知乎小号进行测试。

如果您没有多余的手机号,可以通过Google搜索“receive sms online”,网上有许多提供免费在线接收短信的号码服务。我注册的小号主页地址为:https://www.zhihu.com/people/xiaoxiaodouzi

首先尝试关注该小号,然后在关注列表中定位到该小号。将鼠标悬停在小号头像上时,会触发一个HTTP网络请求。

请求URL为 https://www.zhihu.com/api/v4/members/xiaoxiaodouzi ,URL末尾的“xiaoxiaodouzi”对应小号主页URL的后半部分,我们将这部分称为url_token。

查看接口的返回数据。


{ 
 ...
 "id":"1da75b85900e00adb072e91c56fd9149",
 "favorite_count":0,
 "voteup_count":0,
 "commercial_question_count":0,
 "url_token":"xiaoxiaodouzi",
 "type":"people",
 "avatar_url":"https://pic1.zhimg.com/v2-ca13758626bd7367febde704c66249ec_is.jpg",
 "is_active":1492224390,
 "name":"\u6211\u662f\u5c0f\u53f7",
 "url":"http://www.zhihu.com/api/v4/people/1da75b85900e00adb072e91c56fd9149",
 "gender":-1
 ...
}

从返回数据中可以清晰看到id字段,这验证了我们之前的猜测:私信接口中的receiver_hash字段实际上就是用户的id。

代码实现

代码实现

至此,私信功能的逻辑已梳理清晰,接下来的代码实现便顺理成章。

用户信息

用户信息

为了获取私信接口所需的receiver_hash字典,我们需要先获取用户信息,其中包含用户的id值。


@need_login
def user(self, url_token):
 """
 获取用户信息,
 :param url_token:
 url_token 是用户主页url中后面部分
 例如: https://www.zhihu.com/people/xiaoxiaodouzi
 url_token 是 xiaoxiaodouzi
 :return:dict
 """
 response = self._session.get(URL.profile(url_token))
 return response.json()

发送私信

发送私信


@need_login
def send_message(self, user_id, content):
 """
 给指定的用户发私信
 :param user_id: 用户ID
 :param content: 私信内容
 """
 data = {"type": "common", "content": content, "receiver_hash": user_id}
 response = self._session.post(URL.message(), json=data)
 data = response.json()
 if data.get("error"):
 self.logger.info("私信发送失败, %s" % data.get("error").get("message"))
 else:
 self.logger.info("发送成功")
 return data

上述两个方法均封装在名为Zhihu的类中,此处仅列出关键代码。其中涉及的@need_login是一个用户认证装饰器,表明该方法需在登录后方可执行。细心的读者可能会发现,每个请求中并未显式指定Header字段,这是因为我在__init__.py方法中进行了统一初始化。


def __init__(self):
 self._session = requests.session()
 self._session.verify = False
 self._session.headers = {"Host": "www.zhihu.com",
    "Referer": "https://www.zhihu.com/",
    'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_5) AppleWebKit/537.36'
      ' (KHTML, like Gecko) Chrome/56.0.2924.87',
    }
 self._session.cookies = cookiejar.LWPCookieJar(filename=cookie_filename)
 try:
 self._session.cookies.load(ignore_discard=True)
 except:
 pass

调用执行

调用执行


from zhihu import Zhihu

if __name__ == '__main__':
 zhihu = Zhihu()
 profile = zhihu.user("xiaoxiaodouzi")
 _id = profile.get("id")
 zhihu.send_message(_id, "你好,这是来自Python之禅的问候")

执行完成后,小号成功收到了我发送的私信。

最后,我们可以按照类似的思路,实现关注用户、点赞等其他功能。

源码地址:https://github.com/lzjun567/zhihu-api

在线下载:http://xiazai.jb51.net/201705/yuanma/zhihu-api(jb51.net).rar

总结

总结

以上就是本文的全部内容,希望本文的内容对大家学习或者使用python能带来一定的帮助,如果有疑问大家可以留言交流,谢谢大家对本站的支持。

本站声明

本文内容仅供参考,不代表本站观点。转载或引用请注明出处。如发现内容问题,请通过联系我们页面反馈。

Python 相关产品和应用

全部下载

专题列表