使用Tweepy获取多区域流用于GIS项目遇参数问题,求可行替代方案
Hey there, let's work through this Tweepy issue you're hitting for your GIS project! First, let's fix the immediate problem with the locations parameter, then cover alternative approaches since multi-threaded multi-auth is blocked by IP checks.
First: Fix the locations Parameter Usage
Your current code uses a set of nested lists, which isn't what Tweepy/Twitter's API expects. The locations parameter needs to be a flattened list of coordinates where each rectangular region is defined by four values: [west, south, east, north], and multiple regions are just appended one after another in the same list.
Here's the corrected version of your code:
l = StdOutListener() stream = Stream(auth, l) # Flatten the coordinates of both regions into a single list stream.filter(locations=[-4.62,41.97,10.49,51.1,-87.6,24.73,-75.41,32.12])
Twitter's API natively supports multiple regions in a single stream via this flattened format, so this should work as long as you don't exceed the API's reasonable limits on the number of regions for most GIS use cases.
Alternative Approaches (If Flattened Locations Aren't Enough)
If you need more flexibility or run into API limits for regions, here are two solid workarounds that don't require multi-auth/multi-threading:
1. Post-Stream Geospatial Filtering
Instead of relying on the API's locations filter, listen to a broader geographic area that covers all your target regions, then filter the tweets yourself in your listener code. This lets you define as many regions as you want without hitting API restrictions.
You can use a library like shapely to easily check if a tweet's coordinates fall within your target polygons:
- First install shapely:
pip install shapely - Update your listener class to include the filtering logic:
from shapely.geometry import Point from shapely.geometry.polygon import Polygon from tweepy import StreamListener # Define your target regions as polygons target_regions = [ # First rectangle: [west, south] → [east, south] → [east, north] → [west, north] Polygon([(-4.62,41.97), (10.49,41.97), (10.49,51.1), (-4.62,51.1)]), # Second rectangle Polygon([(-87.6,24.73), (-75.41,24.73), (-75.41,32.12), (-87.6,32.12)]) ] class StdOutListener(StreamListener): def on_status(self, status): # Skip tweets with no geographic data if not hasattr(status, 'coordinates') or status.coordinates is None: return True # Convert tweet coordinates to a shapely Point tweet_point = Point(status.coordinates['coordinates'][0], status.coordinates['coordinates'][1]) # Check if the point falls in any target region for region in target_regions: if region.contains(tweet_point): # Process the tweet (e.g., save to your GIS dataset) print(f"Relevant tweet: {status.text}") break return True
Then start your stream with a broad location that covers all your regions (or even use no location filter if you want, though that will process more data).
2. Use Twitter API v2 with Rule-Based Filtering
If you're open to switching to Tweepy's API v2 support, you can create more flexible filtering rules that include geographic conditions. For example, you can define rules like:
point_radius:[45.5231,-122.6765 10mi](tweets within 10 miles of a point)place:US-CA(tweets tagged with California)
You can add multiple rules to a single stream, which lets you target multiple regions without flattening coordinates. This approach is more powerful for complex geographic filtering, though you'll need to make sure you have the right API v2 access permissions.
内容的提问来源于stack exchange,提问作者BryceSoker

