首页 > 解决方案 > 在while循环python之前是否需要实例化变量

问题描述

我正在尝试使用 reddit api 抓取更多 500 个帖子 - 没有 praw。但是,由于我一次只允许 100 个帖子,我将抓取的对象保存在一个名为的数组中subreddit_content,并将一直抓取到subreddit_content.

下面的代码给了我NameError: name 'subreddit_content_more' is not definedsubreddit_data_more = None如果我在 while 循环之前实例化,我得到TypeError: 'NoneType' object is not subscriptable. 我用 for 循环尝试了同样的事情,但得到了相同的结果。

编辑:更新的代码,while 循环现在使用subreddit_data而不是subreddit_data_more,但现在TypeError: 'Response' object is not subscriptable尽管转换subreddit_data为 json。

    subreddit_data = requests.get(f'https://api.reddit.com/r/{subreddit}/hot?limit=100', headers={'User-Agent': 'windows:requests (by /u/xxx)'}) 
    subreddit_content = subreddit_data.json()['data']['children']
    lastline_json = subreddit_content[-1]['data']['name'] 

    while (len(subreddit_content) < 500):
        subreddit_data = requests.get(f'https://api.reddit.com/r/{subreddit}/hot?limit=100&after={lastline_json}', headers={'User-Agent': 'windows:requests (by /u/xxx)'})
        subreddit_content = subreddit_content.append(subreddit_data.json()['data']['children'])
        lastline_json = subreddit_data[-1]['data']['name']  
        time.sleep(2.5)            

EDIT2:使用.extend而不是.append和删除循环中的变量赋值似乎可以解决问题。这是工作代码的片段(为了便于阅读,我还重命名了我的变量,由 Wups 提供):

    data = requests.get(f'https://api.reddit.com/r/{subreddit}/hot?limit=100', headers={'User-Agent': 'windows:requests (by /u/xxx)'}) 
    content_list = data.json()['data']['children']
    lastline_name = content_list[-1]['data']['name'] 

  while (len(content_list) < 500):
        data = requests.get(f'https://api.reddit.com/r/{subreddit}/hot?limit=100&after={lastline_name}', headers={'User-Agent': 'windows:requests (by /u/xxx)'})
        content_list.extend(data.json()['data']['children'])
        lastline_name = content_list[-1]['data']['name']
        time.sleep(2)   

标签: pythonjsonloopswhile-loop

解决方案


您只想将一个列表添加到另一个列表,但您做错了。一种方法是:

the_next_hundred_records = subreddit_data.json()['data']['children']
subreddit_content.extend(the_next_hundred_records)

在https://docs.python.org/3/tutorial/datastructures.html比较 append 和 extend

您对 append 所做的是将下一个 100 的完整列表添加为位置 101 的单个子列表。然后,因为 list.append 返回 None,您设置 subreddit_content = None

让我们尝试一些较小的数字,这样您就可以看到调试器中发生了什么。这是您的代码,超级简化,除了请求从 subreddit 获取列表之外,我只是做了一个小列表。一样的,真​​的。我使用十的倍数而不是 100。

def do_query(start):
    return list(range(start, start+10))

# content is initialized to a list by the first query
content = do_query(0)
while len(content) < 50:
    next_number = len(content)
    # there are a few valid ways to add to a list. Here's one.
    content.extend(do_query(next_number))
    
for x in content:
    print(x)

使用生成器会更好,但也许这是以后的话题。此外,如果 subreddit 的实际记录少于 500 条,您可能会遇到问题。


推荐阅读