In praw, I'm trying to print the comment body, but what if I encounter an empty comment?
Asked Answered
A

1

7

I am trying to print all the comments from the top posts of a subreddit so that my bot can analyse them. I had it running earlier in the day, but I tried running it now and I have come across an error.

Here is my code:

r = praw.Reddit('Comment crawler v1.0 by /u/...')
r.login('username', 'password')
subreddit=r.get_subreddit('subreddit')
post_limit = 25
subreddit_posts = subreddit.get_hot(limit=post_limit)
subids = set()
for submission in subreddit_posts:
    subids.add(submission.id)
subid = list(subids)

i=0
while i < post_limit:
    submission = r.get_submission(submission_id=subid[i])
    flat_comments = praw.helpers.flatten_tree(submission.comments)
    with open('alreadydone.txt', 'r') as f:
        already_done = [line.strip() for line in f]
    f.close()
    for comment in flat_comments:
        if "Cricketbot, give me Australian news" in **comment.body** and comment.id not in already_done:
            info = feedparser.parse(Australia) #Australia gives a link to an RSS feed.

The starred section is where I am having the issue. I am trying to look through comments which have "Cricketbot, give me Australian news" written in them. Unfortunately, if the body of the comment isn't there, i.e. the comment is empty, the code returns an Attribute error and says that comment has no attribute 'body'.

How does one get around this issue?

Ahithophel answered 2/7, 2013 at 16:6 Comment(0)
B
15

It usually helps to add the stacktrace so people can see the actual error. However, as the PRAW maintainer, I know the error is something like MoreComments type has no attribute body.

There are three simple ways to handle your problem. The first is to simply wrap the if "Cricketbot" statement in a try/except and ignore the attribute error.

try:
    if "Cricketbot..."
        ...
except AttributeError:
    pass

That's not terribly exciting though. The second method is to ensure you're actually working with an object that has a body attribute which can be done in two ways:

The first is to explicitly check if the attribute exists:

for comment in flat_comments:
    if not hasattr(comment, 'body'):
        continue
    ...

The second is to verify you are actually working with Comment objects rather than the MoreComments object:

for comment in flat_comments:
    if not isinstance(comment, praw.objects.Comment):
        continue
    ...

However, when running any of the above solutions, you are effectively not processing all the comments on a submission as you're missing anything that's hidden behind a MoreComments object [ref]. To replace the MoreComments object with some (replacing all can be very inefficient) of the comments requires usage of the replace_more_comments function before flattening the tree:

submission = r.get_submission(submission_id=subid[i])
submission.replace_more_comments(limit=16, threshold=10)
flat_comments = praw.helpers.flatten_tree(submission.comments)

Setting limit=16 and threshold=10 means make no more than 16 additional requests, and only make requests that will result in at least 10 additional comments. You can play with those values as you wish, but note that each replacement requires an additional request (2 seconds) and some only yield as few as one comment.

I hope that helps.

Bolingbroke answered 2/7, 2013 at 16:37 Comment(3)
Thank you very much! Apologies as well, it was indeed AttributeError: '<class 'praw.objects.MoreComments'>' has no attribute 'body'. I wrapped it in try and except and that worked, but the other one doesn't work (read, 'I don't understand how to use it'). It seems that it checks to see if the body exists, but then after the pass command, it just runs the code anyway.Ahithophel
Oops, it should be a continue, not a pass in the other examples. Fixed.Bolingbroke
That makes sense now. Thank you once again!Ahithophel

© 2022 - 2024 — McMap. All rights reserved.