Pergunta

Here is part of my code from a project where I am trying to stream tweets, which I plan to save into a database in Google App Engine. It is important for me to be able to get the lat and long values for the coordinates. (I plan to plot these later.)

The current results look something like this...

'tweet text'@REDACTED Not sure, to be honest... As a Google product, you'd think so. They may have an official extension in the web store. \ 'User Name'REDACTED \ 'Created at't2013-09-26 08:39:45 \ 'Created with'tTwitter for Android \ 'geo't{u'type': u'Point', u'coordinates': [52.569001, -2.7846582]}\ 'coordinates't{u'type': u'Point', u'coordinates': [-2.7846582, 52.569001]}

What I would love to do is to change where it says "if status.coordinates is not None" to check if the coordinates are within a range. ie Lat 50 - 55 and long 0 - 5.

Thank you! :)

class CustomStreamListener(tweepy.StreamListener):

    def on_status(self, status):

        if status.coordinates is not None:
            try:
                print "'tweet text'%s\n\ 'User Name't%s\n\  'Created at't%s\n\  'Created with't%s\n\ 'geo't%s\ 'coordinates't%s" % (status.text, 
                                  status.author.screen_name, 
                                  status.created_at, 
                                  status.source,
                                  status.geo,
                                  status.coordinates)
            except Exception, e:
                print >> sys.stderr, 'Encountered Exception:', e
                pass

    def on_error(self, status_code):
        print >> sys.stderr, 'Encountered error with status code:', status_code
        return True # Don't kill the stream

    def on_timeout(self):
        print >> sys.stderr, 'Timeout...'
        return True # Don't kill the stream
Foi útil?

Solução 3

Thank you to @Alfe and @Hellsgate for their help and suggestions.

The following code works (Currently Hellsgate's code above returns geotagged tweets but doesn't filter by coordinates.)

Above the CustomStreamListener, you just need to add the import statements and the OAuth method. The code below will only return tweets from a box around the UK for the search terms "Rarity Diamonds,Applejack,Discord"

class CustomStreamListener(tweepy.StreamListener):

def check_coords(self, status):
    if status.coordinates is not None:
        lat = status.coordinates['coordinates'][1]
        lng = status.coordinates['coordinates'][0]        
        return 49.7 < lat < 58.5 and -6 < lng < 2.1

def on_status(self, status):


    if self.check_coords(status):
        # if check_coords returns true, the following will run
        try:
            print "'tweet text'%s\n\ 'User Name't%s\n\  'Created at't%s\n\  'Created with't%s\n\ 'geo't%s\ 'coordinates't%s" % (status.text, 
                              status.author.screen_name, 
                              status.created_at, 
                              status.source,
                              status.geo,
                              status.coordinates)
        except Exception, e:
            print >> sys.stderr, 'Encountered Exception:', e
            pass

def on_error(self, status_code):
    print >> sys.stderr, 'Encountered error with status code:', status_code
    return True # Don't kill the stream

def on_timeout(self):
    print >> sys.stderr, 'Timeout...'
    return True # Don't kill the stream


streaming_api = tweepy.streaming.Stream(auth, CustomStreamListener(), timeout=60)


print >> sys.stderr, 'Filtering the public timeline for "%s"' % (' '.join(sys.argv[1:]),)
"""For track=[""], put in words to search for. Commas separate individual terms IE"Applejack, Discord",
to search for tweets containing more than one term, separate keywords with a space. IE "Rarity Diamonds" """
streaming_api.filter(follow=None, track=["Rarity Diamonds,Applejack,Discord"])

Outras dicas

You might want to decide based on the great-circle distance of two points on the earth:

from math import *

def great_circle_distance(coordinates1, coordinates2):
  latitude1, longitude1 = coordinates1
  latitude2, longitude2 = coordinates2
  d = pi / 180  # factor to convert degrees to radians
  return acos(sin(longitude1*d) * sin(longitude2*d) +
              cos(longitude1*d) * cos(longitude2*d) *
              cos((latitude1 - latitude2) * d)) / d

def in_range(coordinates1, coordinates2, range):
  return great_circle_distance(coordinates1, coordinates2) < range

Keep in mind that 90 degrees of the earth represent traditionally 10000 kilometers (AFAIK that's an ancient definition of the meter), so to get a radius of 10km, just use 0.09 degrees.

Assuming that the coordinates are given in the format [latitude, longitude] you can check them as follows:

def check_coords(coords):
    lat = coords[0]
    lng = coords[1]
    return 50 < lat < 55 and 0 < lng < 55

This will return True if latitude is between 50 - 55 and longitude is between 0 - 5. If either is outside their defined range, the function will return False

EDIT: Adding this to your class will make it look like this:

class CustomStreamListener(tweepy.StreamListener):

    def on_status(self, status):

        if status.coordinates is not None:
            # coordinates_in_range will be either True or False
            coordinates_in_range = self.check_coords(status.coordinates['coordinates'])
            try:
                print "'tweet text'%s\n\ 'User Name't%s\n\  'Created at't%s\n\  'Created with't%s\n\ 'geo't%s\ 'coordinates't%s" % (status.text, 
                                  status.author.screen_name, 
                                  status.created_at, 
                                  status.source,
                                  status.geo,
                                  status.coordinates)
            except Exception, e:
                print >> sys.stderr, 'Encountered Exception:', e
                pass

    def on_error(self, status_code):
        print >> sys.stderr, 'Encountered error with status code:', status_code
        return True # Don't kill the stream

    def on_timeout(self):
        print >> sys.stderr, 'Timeout...'
        return True # Don't kill the stream

    def check_coords(self, coords):
        latitude, longitude = coords
        return 50 < latitude < 55 and 0 < longitude < 55
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top