Python爬虫实战:利用requests构建知乎私信API
本文基于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能带来一定的帮助,如果有疑问大家可以留言交流,谢谢大家对本站的支持。
本站声明
本文内容仅供参考,不代表本站观点。转载或引用请注明出处。如发现内容问题,请通过联系我们页面反馈。













