Python函数类

时间:2014-01-03 00:48:56

标签: python json facebook class python-2.7

相关:Facebook Python " ValueError: too many values to unpack"

感到困惑,真的很想明白......

我知道这个API网址会返回我想要的Json数据:“https://graph.facebook.com/search?q=moving&type=post&limit=10000&access_token=XXXXXX|XXXXXXX

示例数据:

{"data":[{"id":"100003992227166_343136419162763",
          "from":{"name":"Taiwo Babalola Oladele","id":"100003992227166"},
          "story":"Taiwo Babalola Oladele shared Gloria Copeland's status update.",
          "story_tags":{"0":[{"id":"100003992227166",
                              "name":"Taiwo Babalola Oladele",
                              "offset":0, "length":22, "type":"user"},],
                       "30":[{"id":"109580399076690",
                              "name":"Gloria Copeland",
                              "offset":30,"length":15,"type":"page"},

所以我在上面的代码中尝试了上面的API URL来构建.csv:

#!/usr/bin/python
# -*- coding: utf-8 -*-

import csv
import json
import urllib
import sys
import time
import re

class FacebookSearch:
    def __init__(self,
        query   = 'https://graph.facebook.com/search.{mode}?{query}&{access_token}'
    ):
        access_token = 'XXXXXX|XXXXX'

    def search(self, q, mode='json', **queryargs):
        queryargs['q'] = q
        query = urllib.urlencode(queryargs)
        return query


def write_csv(fname, rows, header=None, append=False, **kwargs):
    filemode = 'ab' if append else 'wb'
    with open(fname, filemode) as outf:
        out_csv = csv.writer(outf, **kwargs)
        if header:
            out_csv.writerow(header)
        out_csv.writerows(rows)

def main():
    ts = FacebookSearch()
    data = ts.search('appliance', type='post')
    js = json.loads(data)



    messages = ([msg['created_time'],  msg['id']] for msg in js.get('data', []))

    write_csv('fb_washerdryer.csv', messages, append=True)

if __name__ == '__main__':
    main()

我得到了追溯:

Traceback (most recent call last):
  File "./facebook_washer_dryer1.sh", line 43, in <module>
    main()
  File "./facebook_washer_dryer1.sh", line 34, in main
    js = json.loads(data)
  File "/usr/lib64/python2.6/json/__init__.py", line 307, in loads
    return _default_decoder.decode(s)
  File "/usr/lib64/python2.6/json/decoder.py", line 319, in decode
    obj, end = self.raw_decode(s, idx=_w(s, 0).end())
  File "/usr/lib64/python2.6/json/decoder.py", line 338, in raw_decode
    raise ValueError("No JSON object could be decoded")
ValueError: No JSON object could be decoded
[ec2-user@ip-172-31-46-164 ~]$

我理解相关链接上的人说的是什么,但我想我有点不这样做。

我不确定何时定义我的搜索类我做错了。

1 个答案:

答案 0 :(得分:2)

您还没有编写任何甚至构建该URL的代码,更不用说在该URL下载文档的代码了。

作为旁注,您在此处(以及原始问题中)发布的代码中包含一些SyntaxError,使其无法使用。此外,您正在使用Python 2.6,但是定义没有基类的类,这意味着您将获得经典类 - 您不希望这样。我会随着时间的推移解决这两个问题。


首先,在您的__init__方法中,您创建了几个局部变量queryaccess_token,然后对它们不执行任何操作。这不会对你有任何帮助。如果要创建其他方法可以使用的变量,则必须创建对象的属性,而不是局部变量。像这样:

class FacebookSearch(object):
    def __init__(self):
        self.url_format = 'https://graph.facebook.com/search.{mode}?{query}&{access_token}'
        self.access_token = 'XXXXXX|XXXXX'

现在,您可以使用这些变量。但你必须实际使用它们。要将变量粘贴到格式字符串中,必须在该格式字符串上调用.format方法。像这样:

    def make_search_url(self, q, mode='json', **queryargs):
        queryargs['q'] = q
        query = urllib.urlencode(queryargs)
        url = self.url_format.format(mode=mode, query=query, 
                                     access_token=self.access_token, **queryargs)
        return url

所以,现在我们有一个完整的网址,例如https://graph.facebook.com/search?q=moving&type=post&limit=10000&access_token=XXXXXX|XXXXXXX。到现在为止还挺好。但那仍然只是一个URL - 一个字符串。您希望在该URL处获取文档。为此,您需要调用一些下载URL的函数。像urllib2.urlopen

    def search(self, q, mode='json', **queryargs):
        url = self.make_search_url(q, mode, **queryargs)
        page = urllib2.urlopen(url)
        return page.read()

现在 我们有一个方法,您可以调用该方法从查询中构建URL,在该URL处查找资源,并从该资源返回数据。所以现在我们越来越近了。你可以这样称呼它:

data = ts.search('appliance', type='post')

然而,还有一个问题。那type='post'不会做任何事情。您将其传递给search。然后search将其传递给make_search_url。将其传递给format。然后,由于格式字符串中没有名为type的占位符,因此它什么都不做。

我不确定你想在这里用type='post'做什么。如果你想让它为请求使用POST而不是GET ...那么你不应该首先在你的URL中放置查询字符串。如果你想让它做一些与众不同的事情,我无法猜出那些不同的东西。

这里的简单解决方案是,如果您不知道为什么要这样做,请不要这样做:

data = ts.search('appliance')

现在这将返回404,因为在最后粘贴XXXXXX|XXXXX显然不会起作用。它必须是access_token=XXXXXXXX形式的某种形式,并且XXXXXXXX必须是您从OAuth身份验证中获得的令牌,而您在任何地方都没有这样做。