发现新浪提供的python SDK中存在问题,导致无法获取用户所有的关注列表,只能获取前20个。
首先,看看SDK中获取关注列表的函数:
Statuses/friends
获取用户关注列表及每个关注用户的最新一条微博,返回结果按关注时间倒序排列,最新关注的用户排在最前面。
请求参数
必选 | 类型及范围 | 说明 | |
---|---|---|---|
source | true | string | 申请应用时分配的AppKey,调用接口时候代表应用的唯一身份。(采用OAuth授权方式不需要此参数) |
:id | false | int64/string | 用户ID(int64)或者昵称(string)。该参数为一个REST风格参数。调用示例见注意事项 |
user_id | false | int64 | 用户ID,主要是用来区分用户ID跟微博昵称。当微博昵称为数字导致和用户ID产生歧义,特别是当微博昵称和用户ID一样的时候,建议使用该参数 |
screen_name | false | string | 微博昵称,主要是用来区分用户UID跟微博昵称,当二者一样而产生歧义的时候,建议使用该参数 |
cursor | false | int | 用于分页请求,请求第1页cursor传-1,在返回的结果中会得到next_cursor字段,表示下一页的cursor。next_cursor为0表示已经到记录末尾。 |
count | false | int,默认20,最大200 | 每页返回的最大记录数,最大不能超过200,默认为20。 |
:id, user_id, screen_name 可以任选一个参数,在3个都不提供的情况下,系统返回当前登录用户的关注列表 |
从weibopy\api.py下,可获取friends函数的原型:api.friends('id', 'user_id', 'screen_name', 'page', 'cursor')
经过试验,前三个参数只要有一个就可以。现在,修改下例子中的代码examples\getFriends.py:
代码一:
View Code
def friends(self,nickname):
total_friends = 0
next_cursor = -1
while next_cursor != 0:
timeline = self.api.friends(nickname,'','','',next_cursor)
#timeline = self.api.friends()
if isinstance(timeline, tuple):
next_cursor = timeline[1]
total_friends += len(timeline[0])
for line in timeline[0]:
self.obj = line
fid = self.getAtt("id")
name = self.getAtt("screen_name")
text = "friends---"+ str(fid) +":"+ name
text = text.encode("gbk")
print text
else:
next_cursor = 0
total_friends += len(timeline)
for line in timeline:
self.obj = line
fid = self.getAtt("id")
name = self.getAtt("screen_name")
text = "friends---"+ str(fid) +":"+ name
text = text.encode("gbk")
print text
问题出来了,文档里说返回结果中会有next_cursor字段,但是调试发现timeline的类型不是tuple,而是<class 'weibopy.models.ResultSet'>。这是怎么回事?
重新调试,在
timeline = self.api.friends(nickname,'','','',next_cursor)
处步入,来到如下位置(weibopy\binder.py):
def _call(api, *args, **kargs):
method = APIMethod(api, args, kargs)
return method.execute()
进入method.execute(),单步运行来到以下代码行(weibopy\binder.py):
# Parse the response payload
result = self.api.parser.parse(self, body)
再次步入,可发现如下代码(weibopy\parsers.py):
if isinstance(json, tuple):
json, cursors = json
else:
cursors = None
if method.payload_list:
result = model.parse_list(method.api, json)
else:
result = model.parse(method.api, json)
if cursors:
return result, cursors
else:
return result
此时,json的类型不是tuple而是dict,因此,cursors被置为None,因此最后返回的结果中没有cursors,只有关注列表。这导致函数friend中的循环只执行了一次。知道原因就好办了:
if isinstance(json, tuple):
json, cursors = json
elif isinstance(json, dict):
if 'next_cursor' in json:
cursors = json['next_cursor']
else:
cursors = None
else:
cursors = None
重新执行代码一可获得用户的全部关注列表。