Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
c86c9f6
2017.04.24
6xian Apr 24, 2017
f1c369c
Merge remote-tracking branch 'upstream/master'
6xian Apr 24, 2017
42871e1
add unfollow function
MaxPoon Apr 23, 2017
4d4eb85
update README.md
MaxPoon Apr 23, 2017
122d425
add test cases for follow and unfollow
MaxPoon Apr 25, 2017
6903db1
add zhuanlan host
lzjun567 Apr 28, 2017
7e0da35
Merge branch 'develop'
lzjun567 Apr 28, 2017
c557254
add UserAgent list
Oopswc Apr 28, 2017
91225b4
Update settings.py
Oopswc Apr 28, 2017
8365a25
Merge pull request #16 from Oopswc/Add_UA
lzjun567 Apr 28, 2017
5beb914
Merge pull request #8 from MaxPoon/unfollow
lzjun567 Apr 28, 2017
f90e37b
update readme
lzjun567 Apr 28, 2017
c333a26
Merge branch 'master' of github.com:lzjun567/zhihu-api
lzjun567 Apr 28, 2017
b28a7df
fix test
lzjun567 Apr 28, 2017
ecf1df4
update readme
lzjun567 Apr 28, 2017
368664e
update readme
lzjun567 Apr 28, 2017
d128c12
Merge remote-tracking branch 'upstream/master'
6xian Apr 29, 2017
bd7dbbb
refactor login
lzjun567 May 1, 2017
63e480b
Merge pull request #1 from lzjun567/master
Oopswc May 2, 2017
28eca66
fix phonenum match
Oopswc May 2, 2017
aa83de5
Merge pull request #21 from Oopswc/phone_re_match
lzjun567 May 2, 2017
b2e0368
fix document error charactor
lzjun567 May 2, 2017
ef86c3e
Merge branch 'master' of github.com:lzjun567/zhihu-api
lzjun567 May 2, 2017
7a79d2a
remove unneccsary comment
lzjun567 May 2, 2017
98ee3df
2017.05.06 add userasks function
6xian May 6, 2017
d569c1b
add userasks function
6xian May 6, 2017
ed00172
add test/userasks.py
6xian May 6, 2017
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
85 changes: 46 additions & 39 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
## 项目简介

### 目标

试图构建一个更加简洁、优雅的、Pythonic 的知乎 API。

### 使用场景
* 如果你想自动给你喜欢的人点赞
* 如果你想基于知乎社区做数据分析
* 如果你想通过程序自动给回答点赞
* 如果你想批量关注用户
* 如果你想批量发送信息
* 如果你想构建一个自己的知乎客户端
Expand All @@ -22,21 +21,16 @@
## 安装

```python
pip install git+git://github.com/lzjun567/zhihu-api

# 升级到最新的代码,附加参数 --upgrade
# 推荐
pip install git+git://github.com/lzjun567/zhihu-api --upgrade
```

### API

## API

### 用户个人公开信息
**个人信息**
```
>>> from zhihu.zhihu import Zhihu
>>> zhihu = Zhihu()
>>> zhihu.user(profile_url="https://www.zhihu.com/people/xiaoxiaodouzi")
>>> zhihu.user(user_slug="xiaoxiaodouzi")

{'avatar_url_template': 'https://pic1.zhimg.com/v2-ca13758626bd7367febde704c66249ec_{size}.jpg',
'badge': [],
Expand All @@ -51,64 +45,77 @@ pip install git+git://github.com/lzjun567/zhihu-api --upgrade
'id': '1da75b85900e00adb072e91c56fd9149',
'is_org': False}

# 还可以用
>>> zhihu.user(user_slug="xiaoxiaodouzi")

```

### 私信发送


**私信发送**

```python
>>> zhihu.send_message("你好,问候3", user_id="1da75b85900e00adb072e91c56fd9149")

# 还支持 user_slug
>>> zhihu.send_message("你好,问候2", user_slug="xiaoxiaodouzi")

# 还支持 profile_url
>>> zhihu.zhihu.send_message("你好,问候1", profile_url="https://www.zhihu.com/people/xiaoxiaodouzi")
```

### 关注用户
**关注用户**
```
>>> zhihu.follow(profile_url="https://www.zhihu.com/people/gao-yu-dong-41")
{"follower_count": 6}

>>> zhihu.follow(user_slug="xiaoxiaodouzi")
{"follower_count": 6}
```
**取消关注**
```
>>> zhihu.unfollow(user_slug="xiaoxiaodouzi")
{'follower_count': 5}
```

### 点赞
**点赞回答**
```
>>> from zhihu import Answer
>>> data = Answer(id=14005147).vote_up()
>>> data
>>> {"voting": 1, "voteup_count": 314}
```

>>> data = Answer(url="https://www.zhihu.com/question/19761434/answer/14005147").vote_up()
**反对**
```
>>> from zhihu import Answer
>>> data = Answer(id=14005147).vote_down()
>>> data
>>> {"voting": 1, "voteup_count": 314}
```

### 反对
vote_down

### 中立
vote_neutral
**中立**
```
>>> from zhihu import Answer
>>> data = Answer(id=14005147).vote_neutral()
>>> data
>>> {"voting": 1, "voteup_count": 314}
```


**专栏的关注列表**
```
>>> from zhihu import Column
>>> column = Column(url="https://zhuanlan.zhihu.com/pythoneer")
>>> column.followers(limit=2, offset=1)
[{u'bio': u'python', u'hash': u'463e2651f6a856d88c33bfb7fd673bf4', u'description': u'', u'isOrg': False,
u'name': u'zpf1024', u'profileUrl': u'https://www.zhihu.com/people/zpf1024',
u'avatar': {u'id': u'da8e974dc', u'template': u'https://pic1.zhimg.com/{id}_{size}.jpg'},
u'isOrgWhiteList': False, u'slug': u'zpf1024', u'uid': 841267452498296832L},
{u'bio': None, u'hash': u'45bbaa0aca55fec0d768ccb4845a1c53', u'description': u'', u'isOrg': False,
u'name': u'keyoka', u'profileUrl': u'https://www.zhihu.com/people/yi-hu-84',
u'avatar': {u'id': u'785bfd914', u'template': u'https://pic1.zhimg.com/{id}_{size}.jpg'},
u'isOrgWhiteList': False, u'slug': u'yi-hu-84', u'uid': 43738302775296L}]
```

## TODO
每个接口都提供了不只一种方式调用,更多参考单元测试里面的例子

* 文章点赞
* ...

## 贡献者
欢迎 PR, 所有贡献者都将出现在这里,排名部分先后
欢迎 PR, 所有贡献者都将出现在这里,排名不分先后

* [@BigBorg](https://github.com/BigBorg)
* [@xiaowenlong100](https://github.com/xiaowenlong100)
* [chenghengchao](https://github.com/chenghengchao)
* [MaxPoon](https://github.com/MaxPoon)
* [@chenghengchao](https://github.com/chenghengchao)
* [@MaxPoon](https://github.com/MaxPoon)
* [@Oopswc](https://github.com/Oopswc)

## 交流
群已经加不进,可以先加微信:lzjun567 拉你入群
Expand Down
14 changes: 14 additions & 0 deletions doc.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@

### Account
账户类

**登录**

```

>>> from zhihu import Account
>>> account = Account()
>>> account.login("12334@qq.com", "xxxxxx")
>>>

```
5 changes: 2 additions & 3 deletions test/answer.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,11 +34,10 @@ def test_vote_neutral_with_url(self):
def test_thank_with_url(self):
time.sleep(1)
data = Answer(url="https://www.zhihu.com/question/19761434/answer/14005147").thank()
self.assertIn("is_thanked", data)
self.assertIn("true", data)
self.assertEqual({"is_thanked": True}, data)

def test_thank_cancel_with_url(self):
time.sleep(1)
data = Answer(url="https://www.zhihu.com/question/19761434/answer/14005147").thank_cancel()
self.assertIn("is_thanked", data)
self.assertIn("false", data)
self.assertEqual({"is_thanked": False}, data)
16 changes: 7 additions & 9 deletions test/column.py
Original file line number Diff line number Diff line change
@@ -1,19 +1,17 @@
# encoding: utf-8

from zhihu import Column
import unittest
import time

from zhihu import Column


class ColumnTestCase(unittest.TestCase):

def test_followers_with_slug(self):
slug = "pythoneer"
from zhihu import Zhihu
data = Column(slug=slug).followers(limit=10, headers=Zhihu().)
data = Column(slug=slug).followers(limit=10)
self.assertEqual(10, len(data))



# https://zhuanlan.zhihu.com/api/columns/pythoneer/followers
# https://zhuanlan.zhihu.com/api/columns/pythoneer/followers
def test_followers_with_url(self):
url = "https://zhuanlan.zhihu.com/pythoneer"
data = Column(url=url).followers(limit=10)
self.assertEqual(10, len(data))
60 changes: 60 additions & 0 deletions test/common.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@

from zhihu import Zhihu
from zhihu.error import ZhihuError
import time
from zhihu.models import Model


class CommonTestCase(unittest.TestCase):
Expand All @@ -13,3 +15,61 @@ def test_send_message_with_no_kwargs(self):
"""
zhihu = Zhihu()
self.assertRaises(ZhihuError, zhihu.send_message, "hello")

def test_follow_with_no_kwargs(self):
"""
不带关键字参数,抛出异常
:return:
"""
time.sleep(1)
zhihu = Zhihu()
self.assertRaises(ZhihuError, zhihu.follow)

def test_follow_with_url(self):
"""
带url,返回follower数量
:return:
"""
time.sleep(1)
zhihu = Zhihu()
data = zhihu.follow(profile_url="https://www.zhihu.com/people/gao-yu-dong-41")
self.assertIn('follower_count', data)

def test_follow_with_user_slug(self):
"""
带user_slug,返回follower数量
:return:
"""
time.sleep(1)
zhihu = Zhihu()
data = zhihu.follow(user_slug="xiaoxiaodouzi")
self.assertIn('follower_count', data)

def test_follow_with_no_kwargs(self):
"""
不带关键字参数,抛出异常
:return:
"""
time.sleep(1)
zhihu = Zhihu()
self.assertRaises(ZhihuError, zhihu.unfollow)

def test_unfollow_with_url(self):
"""
带url,返回follower数量
:return:
"""
time.sleep(1)
zhihu = Zhihu()
data = zhihu.unfollow(profile_url="https://www.zhihu.com/people/gao-yu-dong-41")
self.assertIn('follower_count', data)

def test_unfollow_with_user_slug(self):
"""
带user_slug,返回follower数量
:return:
"""
time.sleep(1)
zhihu = Zhihu()
data = zhihu.unfollow(user_slug="xiaoxiaodouzi")
self.assertIn('follower_count', data)
14 changes: 6 additions & 8 deletions test/question.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,27 +7,25 @@
class QuestionTestCase(unittest.TestCase):
def test_follow_question_with_id(self):
data = Question(id=32096743).follow_question()
self.assertIn("is_following", data)
self.assertIn("true", data)
self.assertEqual({"is_following": True}, data)

def test_unfollow_question_with_id(self):
data = Question(id=32096743).unfollow_question()
self.assertEqual('', data)
self.assertEqual({"is_following": False}, data)

def test_follow_question_with_url(self):
data = Question(url='https://www.zhihu.com/question/58684385').follow_question()
self.assertIn("is_following", data)
self.assertIn("true", data)
self.assertEqual({"is_following": True}, data)

def test_follow_question_with_answer_url(self):
"""
也支持回答的URL,因为从回答中也能找到问题的ID
:return:
"""
data = Question(url='https://www.zhihu.com/question/59001738/answer/160832685').follow_question()
self.assertIn("is_following", data)
self.assertIn("true", data)
self.assertEqual({"is_following": True}, data)

def test_unfollow_question_with_url(self):
data = Question(url='https://www.zhihu.com/question/58684385').unfollow_question()
self.assertEqual('', data)
self.assertEqual({"is_following": False}, data)

17 changes: 17 additions & 0 deletions test/userasks.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# encoding: utf-8

import unittest

from zhihu import Userasks


class UserasksTestCase(unittest.TestCase):
def test_asks_list_with_slug(self):
slug = "heikehuawuya"
data = Userasks(slug=slug).asks_list()
self.assertIn('黑客电影和现实区别?', data)

def test_asks_list_with_url(self):
url = "https://www.zhihu.com/people/heikehuawuya"
data = Userasks(url=url).asks_list()
self.assertIn('黑客电影和现实区别?', data)
5 changes: 4 additions & 1 deletion zhihu/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,11 @@
from zhihu.models import common
from zhihu.models import question
from zhihu.models import column
from zhihu.models import account
from zhihu.models import userasks

Answer = answer.Answer
Zhihu = common.Common
Question = question.Question
Column = column.Column
Account = account.Account
Userasks = userasks.Userasks
12 changes: 8 additions & 4 deletions zhihu/auth.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,25 +2,29 @@

import os

from zhihu.models import Model
from zhihu.models import account
from zhihu.settings import COOKIES_FILE

try:
input = raw_input # py2
except:
pass


def need_login(func):
"""
用户认证装饰器(判断用户是否已经登录)
"""

def wrapper(self, *args, **kwargs):
assert isinstance(self, Model)
success = True
# TODO 1. 不能这样简单粗暴判断cookie文件存不存在,因为有可能文件里面的cookie信息已经过期,也有可能只是一个空文件
if not os.path.exists(COOKIES_FILE):
success = False
while not success:
email = input("请输入email:")
email = input("请输入email或者手机号码:")
password = input("请输入密码:")
success = self.login(email, password)
success = account.Account().login(email, password)
if success:
result = func(self, *args, **kwargs)
return result
Expand Down
Loading