python爬虫入门教程--利用requests构建知乎API(三)


Posted in Python onMay 25, 2017

前言

在爬虫系列文章 优雅的HTTP库requests 中介绍了 requests 的使用方式,这一次我们用 requests 构建一个知乎 API,功能包括:私信发送、文章点赞、用户关注等,因为任何涉及用户操作的功能都需要登录后才操作,所以在阅读这篇文章前建议先了解Python模拟知乎登录 。现在假设你已经知道如何用 requests 模拟知乎登录了。

思路分析

发送私信的过程就是浏览器向服务器发送一个 HTTP 请求,请求报文包括请求 URL、请求头 Header、还有请求体 Body,只要把这些信息弄清楚,那么就很容易用 requests 来模拟浏览器发送私信了。

打开 Chrome 浏览器,随便找一个用户,点击发送私信,追踪一下私信的网络请求过程。

先看下请求头信息

python爬虫入门教程--利用requests构建知乎API(三)

请求头 Header 中有 cookies 登录信息,此外还有一个 authorization 字段,该字段是用于用户认证的,同时这个字段也存在 cookies 中(为了防止 cookie 信息泄露,我打了马赛克), requests 请求时这些信息都必须携带上。

再来看看请求的URL和请求体

python爬虫入门教程--利用requests构建知乎API(三)

请求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 网络请求。

python爬虫入门教程--利用requests构建知乎API(三)

请求 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之禅的问候")

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

python爬虫入门教程--利用requests构建知乎API(三)

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

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

在线下载:http://xiazai.3water.com/201705/yuanma/zhihu-api(3water.com).rar

总结

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

Python 相关文章推荐
Python通过PIL获取图片主要颜色并和颜色库进行对比的方法
Mar 19 Python
pandas DataFrame数据转为list的方法
Apr 11 Python
对python中if语句的真假判断实例详解
Feb 18 Python
python程序快速缩进多行代码方法总结
Jun 23 Python
pip指定python位置安装软件包的方法
Jul 12 Python
django 数据库连接模块解析及简单长连接改造方法
Aug 29 Python
Python搭建代理IP池实现获取IP的方法
Oct 27 Python
基于numpy中的expand_dims函数用法
Dec 18 Python
opencv之颜色过滤只留下图片中的红色区域操作
Jun 05 Python
python通过cython加密代码
Dec 11 Python
Python之京东商品秒杀的实现示例
Jan 06 Python
python FTP编程基础入门
Feb 27 Python
Python正则表达式完全指南
May 25 #Python
Tensorflow简单验证码识别应用
May 25 #Python
Python 编码Basic Auth使用方法简单实例
May 25 #Python
Python 含参构造函数实例详解
May 25 #Python
Python爬虫之模拟知乎登录的方法教程
May 25 #Python
python爬虫入门教程--优雅的HTTP库requests(二)
May 25 #Python
Python操作使用MySQL数据库的实例代码
May 25 #Python
You might like
20个2014年最优秀的PHP框架回顾
2014/10/22 PHP
Node.js文件操作详解
2014/08/16 Javascript
AngularJs表单验证实例详解
2016/05/30 Javascript
浅谈jquery设置和获得checkbox选中的问题
2016/08/19 Javascript
网站发布后Bootstrap框架引用woff字体无法正常显示的解决方法
2016/11/24 Javascript
jQuery操作复选框(CheckBox)的取值赋值实现代码
2017/01/10 Javascript
jquery封装插件时匿名函数形参和实参的写法解释
2017/02/14 Javascript
JavaScript实现省市联动过程中bug的解决方法
2017/12/04 Javascript
在vue项目创建的后初始化首次使用stylus安装方法分享
2018/01/25 Javascript
浅析vue-router实现原理及两种模式
2020/02/11 Javascript
JavaScript中变量提升和函数提升的详解
2020/08/07 Javascript
[01:38]【DOTA2亚洲邀请赛】Sumail——梦开始的地方
2017/03/03 DOTA
[02:17]快乐加倍!DOTA2食人魔魔法师至宝+迎霜节活动上线
2019/12/22 DOTA
在Django的模型和公用函数中使用惰性翻译对象
2015/07/27 Python
python笔记:mysql、redis操作方法
2017/06/28 Python
python获取代理IP的实例分享
2018/05/07 Python
python3结合openpyxl库实现excel操作的实例代码
2018/09/11 Python
Python如何发布程序的详细教程
2018/10/09 Python
pandas每次多Sheet写入文件的方法
2018/12/10 Python
PyQt QListWidget修改列表项item的行高方法
2019/06/20 Python
python多线程案例之多任务copy文件完整实例
2019/10/29 Python
如何使用Python破解ZIP或RAR压缩文件密码
2020/01/09 Python
关于Keras Dense层整理
2020/05/21 Python
keras的siamese(孪生网络)实现案例
2020/06/12 Python
Keras搭建自编码器操作
2020/07/03 Python
Flask中jinja2的继承实现方法及实例
2021/03/03 Python
银行职员思想汇报
2013/12/31 职场文书
2014年最新领导班子整改方案
2014/09/27 职场文书
公安民警正风肃纪剖析材料
2014/10/10 职场文书
招标保密承诺书
2015/01/20 职场文书
公司规章制度范本
2015/08/03 职场文书
污染环境建议书
2015/09/14 职场文书
利用python做表格数据处理
2021/04/13 Python
JavaScript实现淘宝商品图切换效果
2021/04/29 Javascript
pytorch 两个GPU同时训练的解决方案
2021/06/01 Python
一文搞懂Python Sklearn库使用
2021/08/23 Python