Instagram Posts Scraper With Tagged Places & Coordinates avatar

Instagram Posts Scraper With Tagged Places & Coordinates

Pricing

from $2.99 / 1,000 results

Go to Apify Store
Instagram Posts Scraper With Tagged Places & Coordinates

Instagram Posts Scraper With Tagged Places & Coordinates

Instagram Posts Scraper — Scrape Instagram posts with captions, media details, likes, timestamps, tagged places, location names, and geographic coordinates. Extract structured location and engagement data for content research, local trend analysis, competitor monitoring, and social insights.

Pricing

from $2.99 / 1,000 results

Rating

0.0

(0)

Developer

SimpleAPI

SimpleAPI

Maintained by Community

Actor stats

0

Bookmarked

12

Total users

2

Monthly active users

3 days ago

Last modified

Share

Instagram Posts Scraper — Tagged Places, Coordinates & Engagement

Instagram Posts Scraper With Tagged Places & Coordinates pulls posts from any public Instagram profile, username, or post shortcode and returns them as structured JSON — post_url, taken_at, like_count, comment_count, plus a taggedPlace object with placeName, GPS lat/lng, address, and city for every geotagged post. Travel marketers, local-content researchers, and geospatial analysts use it to map where an account posts from, not just what it posts. Turn on the only-geotagged filter and each run also adds a per-profile roll-up of that creator's most-tagged places.

What is Instagram Posts Scraper With Tagged Places & Coordinates?

It is an Apify Actor that scrapes posts from a list of Instagram profile URLs, usernames, or post shortcodes and returns one structured JSON row per post, plus an optional per-profile summary row. No Instagram account, login, or session cookie is required — the Actor reads each profile's public page to extract the tokens it needs, then calls Instagram's own post-feed endpoint.

  • 🔗 Flexible targeting — accepts full profile URLs, plain usernames, or post shortcodes in the same list; the type is auto-detected, and shortcodes are resolved to their author's username automatically.
  • 📍 Structured tagged-place fieldsplaceName, lat/lng, address, city, and externalId parsed out of Instagram's raw location object into a clean taggedPlace field, plus a hasLocation flag on every post.
  • 🔎 Only-geotagged modeonlyGeotagged skips posts with no tagged place and keeps scanning further pages until it collects postsPerProfile geotagged posts (or the profile/date range runs out).
  • 🏆 Per-profile top-places roll-uptopPlacesPerProfile adds one locationSummary row per profile, ranking that creator's most-frequently-tagged places by scanned-post count.
  • 📅 Absolute or relative date filteringdateFilterType + filterDate keep only posts newer than a calendar date or a relative window like 30d.
  • 🌐 Proxy-backed requests — every request runs through proxyConfiguration via Actor.create_proxy_configuration, defaulting to Apify's RESIDENTIAL group when left unset.

Results land in the Actor's default dataset and can be downloaded as JSON, CSV, or Excel, or read back with the Apify API — standard Apify dataset export, not a feature specific to this Actor.

What data can I extract with Instagram Posts Scraper?

Every scraped post is returned with the fields below, plus every other field Instagram's own post-feed API includes for that post (media URLs, dimensions, caption object, owner data, and more) — the Actor passes those through verbatim rather than stripping or renaming them.

FieldExample ValueUse Case
type"post" or "locationSummary"Tells you whether the row is a post or the per-profile roll-up
code / short_code"DO8fSwLiNU-"Instagram's shortcode for the post
post_url"https://www.instagram.com/p/DO8fSwLiNU-/"Direct permalink to the post
scraped_username"natgeo"Which profile this row came from
taken_at1758631325Unix timestamp the post was published
scraped_at1758631400Unix timestamp this run collected the row
hasLocationtrueWhether the post's creator tagged a place
taggedPlace.placeId"212988663"Instagram's internal place ID
taggedPlace.placeName"Yellowstone National Park"The tagged place's name
taggedPlace.lat / taggedPlace.lng44.4279 / -110.5885GPS coordinates of the tagged place
taggedPlace.addressnullStreet address, when Instagram has one on file
taggedPlace.city"Yellowstone National Park"City name for the tagged place
taggedPlace.externalIdnullExternal place-directory ID (e.g. Facebook Places), when present
locationraw objectInstagram's unmodified location payload that taggedPlace was parsed from
like_count / comment_count183421 / 942Engagement counts, only present when includeEngagement is on
play_count / view_count52000View counts on video posts, only present when includeEngagement is on
video_versions / video_durationarray / 14.3Video renditions and duration, only present when includeVideoMetadata is on
totalPostsScanned30On locationSummary rows: how many posts this run scanned for the profile
geotaggedPostCount6On locationSummary rows: how many of those were geotagged
geotaggedCoverage0.2On locationSummary rows: geotaggedPostCount / totalPostsScanned
topTaggedPlacesarray of {placeName, postCount, lat, lng, city, address}On locationSummary rows: the profile's most-tagged places, ranked by post count

Tagged-place and roll-up data

taggedPlace is the structured version of whatever Instagram's raw location object carries on a geotagged post: a place ID, name, coordinates, address, and city, plus an externalId when Instagram links the place to an external directory such as Facebook Places. It is null whenever the post has no tagged place — never guessed or backfilled. When topPlacesPerProfile is greater than 0, each profile also gets one extra locationSummary row: totalPostsScanned and geotaggedPostCount for that run, the resulting geotaggedCoverage ratio, and topTaggedPlaces — that profile's most-tagged places ranked by how many scanned posts carried them, each with its own coordinates and city for mapping.

Targeting and segmentation fields

Three fields drive filtering: taken_at is what dateFilterType/filterDate compare against to keep only recent posts; hasLocation is the boolean the onlyGeotagged toggle filters on; scraped_username ties every row (post or summary) back to the profile it came from when you're running multiple profiles in one call and need to split results downstream.

Why not build this yourself?

Instagram's official Graph API and Basic Display API only expose an account's own content to that account's own access token — neither lets a third party pull an arbitrary public profile's posts or tagged-place data in bulk. Building that yourself means reverse-engineering the private feed endpoint: extracting a fresh app_id/csrf_token pair from the profile's public HTML, paging with max_id/next_max_id until more_available goes false, retrying failed requests, and switching from a datacenter to a residential proxy session when a fetch comes back empty. This Actor implements exactly that (get_tokens, fetch_page, and the proxy switch inside scrape_profile), so a run is one API call instead of a scraper you maintain yourself.

How to use data extracted from Instagram?

Travel and hospitality marketing

Run the Actor against a set of destination or venue accounts with onlyGeotagged on and topPlacesPerProfile set to a useful number. Each profile comes back with only its geotagged posts — taggedPlace.lat/lng ready to drop on a map — plus one locationSummary row listing the places that account tags most often, which is the fastest way to see where a creator's audience actually associates them with being.

Marketing and social-media agencies

Agencies running the same audit for several clients or competitors repeatedly can point the Actor at a rolling dateFilterType=relative / filterDate=30d window each month, then compare geotaggedCoverage across accounts to see which ones are actively geotagging content and which have stopped, without opening a single post by hand.

Market research and location intelligence

Aggregating taggedPlace.city, lat, and lng across many profiles' locationSummary rows shows where geotagging activity for a set of accounts clusters — useful for expansion research or spotting which neighborhoods a creator segment associates with most, fed straight into a heat-map or GIS tool from the JSON coordinates.

AI agents and automated pipelines

post_url, taggedPlace, and hasLocation are enough to ground an agent's answers in real, geotagged Instagram content — for example a location-recommendation tool that only surfaces posts Instagram's own location data confirms were taken at the place in question, called on demand through the Apify API.

⬇️ Input sample

All parameters are optional — the schema has no required fields, though profileUrls (or the legacy startUrls) must resolve to at least one entry or the run exits with no data.

ParameterRequiredTypeDescriptionExample Value
profileUrlsNoarrayInstagram profile URLs, bare usernames, or post shortcodes; type is auto-detected. If both profileUrls and startUrls are set, profileUrls wins.["https://www.instagram.com/natgeo/"]
startUrlsNoarrayLegacy alias of profileUrls, kept so existing base-scraper input JSON keeps working.["natgeo"]
postsPerProfileNointegerHow many of each profile's most recent posts to scan for tagged-place data. Min 1, max 1000. No schema default; the UI prefills 10 and the Actor falls back to 10 when omitted. postsPerProfile wins over maxPosts if both are set.50
maxPostsNointegerLegacy alias of postsPerProfile. Min 1, max 1000.50
onlyGeotaggedNobooleanON: skip posts with no tagged place and keep scanning until postsPerProfile geotagged posts are found (or the scan runs out). OFF: return every scanned post. Default false.true
topPlacesPerProfileNointegerHow many of a profile's most-tagged places to list in its roll-up row. Min 0, max 50. Set to 0 to skip the roll-up row. No schema default; the UI prefills 5 and the Actor falls back to 5 when omitted.5
dateFilterTypeNostring"absolute" or "relative". Default "relative"."relative"
filterDateNostringAbsolute mode: YYYY-MM-DD. Relative mode: a value like 7d, 2w, 3m, 1y. Default "" (no filter)."30d"
includeEngagementNobooleanKeep like/comment/view-count fields on each post row. Default false.true
includeVideoMetadataNobooleanKeep video duration, quality-variant, and codec fields on each post row. Default false.false
proxyConfigurationNoobjectApify Proxy configuration for every request this run makes. Defaults to the RESIDENTIAL group when left unset.{ "useApifyProxy": true, "apifyProxyGroups": ["RESIDENTIAL"] }
{
"profileUrls": ["https://www.instagram.com/natgeo/"],
"postsPerProfile": 30,
"onlyGeotagged": true,
"topPlacesPerProfile": 5,
"dateFilterType": "relative",
"filterDate": "90d",
"includeEngagement": true,
"includeVideoMetadata": false,
"proxyConfiguration": { "useApifyProxy": true, "apifyProxyGroups": ["RESIDENTIAL"] }
}

⚠️ Common pitfall: filterDate's format has to match the dateFilterType you picked. The input schema's own pattern accepts both an absolute date and a relative value regardless of which mode is selected, so setting dateFilterType to "absolute" while typing a relative value like "30d" passes validation — but the Actor then tries to parse it as an ISO date, fails silently, and applies no date filter at all instead of raising an error. Match the two fields to the mode you actually chose.

⬆️ Output sample

Output is typed, normalized JSON with a consistent schema across every profile — one array of post rows interleaved with one locationSummary row per profile (when topPlacesPerProfile is greater than 0). Download it from the dataset as JSON, CSV, or Excel, or pull it through the Apify API.

[
{
"type": "post",
"isSummary": false,
"hasLocation": true,
"code": "DO8fSwLiNU-",
"short_code": "DO8fSwLiNU-",
"post_url": "https://www.instagram.com/p/DO8fSwLiNU-/",
"scraped_username": "natgeo",
"taken_at": 1758631325,
"scraped_at": 1758631400,
"like_count": 183421,
"comment_count": 942,
"taggedPlace": {
"placeId": "212988663",
"placeName": "Yellowstone National Park",
"lat": 44.4279,
"lng": -110.5885,
"address": null,
"city": "Yellowstone National Park",
"externalId": null
},
"location": {
"pk": 212988663,
"name": "Yellowstone National Park",
"lat": 44.4279,
"lng": -110.5885,
"city_name": "Yellowstone National Park",
"external_id": null,
"facebook_places_id": null
}
},
{
"type": "locationSummary",
"isSummary": true,
"scraped_username": "natgeo",
"scraped_at": 1758631400,
"totalPostsScanned": 30,
"geotaggedPostCount": 6,
"geotaggedCoverage": 0.2,
"topTaggedPlaces": [
{
"placeName": "Yellowstone National Park",
"postCount": 2,
"lat": 44.4279,
"lng": -110.5885,
"city": "Yellowstone National Park",
"address": null
}
]
}
]

How do you filter and target specific posts?

This Actor's targeting comes down to three real axes, not a category or keyword search — input is always a profile, username, or shortcode.

  1. Date scopedateFilterType chooses absolute (filterDate="2026-01-01") or relative (filterDate="30d") mode; posts older than the cutoff are dropped while scanning, so narrowing the window also reduces run time.
  2. Quality thresholdonlyGeotagged is the actor's precision filter: instead of returning whatever the feed hands back, it keeps scanning further pages specifically until it has postsPerProfile posts that actually carry a tagged place.
  3. Volume controlpostsPerProfile caps how many posts count toward the target per profile, and topPlacesPerProfile caps how many places appear in the roll-up. When onlyGeotagged is on and geotagged posts are sparse for an account, the scan stops after 200 pages regardless of whether the target was reached — the run log reports how many were found before the cap hit.
{ "profileUrls": ["https://www.instagram.com/natgeo/"], "dateFilterType": "relative", "filterDate": "30d", "postsPerProfile": 40 }
{ "profileUrls": ["https://www.instagram.com/natgeo/"], "onlyGeotagged": true, "postsPerProfile": 20, "topPlacesPerProfile": 10 }
{ "profileUrls": ["https://www.instagram.com/natgeo/", "https://www.instagram.com/nasa/"], "postsPerProfile": 100, "topPlacesPerProfile": 0 }

▶️ Want to try other Instagram scrapers?

ScraperWhat it extracts
Instagram Story Details Scraper With Media DetailsStory details per profile, normalized video/image renditions
Instagram Profile Post Scraper With Engagement AnalyticsProfile posts plus per-post and profile-level engagement-rate analytics
TikTok User Profile Scraper: Business LeadsTikTok creator/business profiles with bio-parsed contact fields
Snapchat User Stories Scraper With Creator Profile InsightsSnapchat Stories, Highlights, and creator profile analytics

How to extract Instagram data programmatically

Every run is a standard Apify Actor call: one run-sync/run request with your JSON input, structured JSON back from the dataset.

Python example

from apify_client import ApifyClient
client = ApifyClient("<YOUR_APIFY_TOKEN>")
run = client.actor("instagram-posts-scraper-with-tagged-places-and-coordinates").call(
run_input={
"profileUrls": ["https://www.instagram.com/natgeo/"],
"onlyGeotagged": True,
"postsPerProfile": 20,
"topPlacesPerProfile": 5,
}
)
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
if item.get("type") == "post":
place = item.get("taggedPlace") or {}
print(item["post_url"], place.get("placeName"), place.get("lat"), place.get("lng"))

Export to spreadsheets or CRM

Download the dataset as CSV directly from the Apify Console, or via the API's dataset/{id}/items?format=csv endpoint. Map post_url, scraped_username, taggedPlace.placeName, taggedPlace.lat, and taggedPlace.lng to spreadsheet columns for a location list you can drop straight into a mapping tool or CRM.

Scraping publicly visible Instagram posts is generally lawful — these are posts their creators chose to make public, and this Actor never accesses private accounts or bypasses a login wall. Because a scraped post row carries an identifiable creator (scraped_username) and, when geotagged, a real-world location tied to that person's activity, GDPR and CCPA can apply to how you store and use it depending on your jurisdiction and use case. Instagram's Terms of Service also govern automated access separately from data-protection law. Consult legal counsel for commercial applications involving bulk storage of personal data.

❓ FAQ

What happens if a post is deleted after I scrape it?

The Actor has no deletion-detection flag — a row reflects exactly what Instagram's feed returned at the moment of the run, timestamped by scraped_at. Re-run the Actor against the same profile to get the current state; a post that has since been deleted or made private will simply no longer appear.

Can I get engagement metrics along with tagged-place data?

Yes — set includeEngagement to true and each post row keeps like_count, comment_count, play_count, view_count, and related engagement fields alongside taggedPlace. It's off by default, so engagement fields are stripped from the row unless you turn it on.

How accurate is the tagged-place data?

The Actor returns Instagram's own location object exactly as attached to the post — it never infers or backfills a place. Accuracy depends on whether the creator tagged the correct place at posting time; Instagram's place database, not this Actor, is the source of the coordinates and address.

How many posts can I get per run?

Up to postsPerProfile per profile, capped at 1000 by the input schema. When onlyGeotagged is on, the scan for that profile also stops after 200 feed pages even if the target hasn't been reached — the run log reports how many geotagged posts were found before the cap.

How does the Only Geotagged Posts filter work?

With onlyGeotagged on, the Actor keeps requesting further pages of a profile's feed and discards any post without a tagged place, stopping once it has postsPerProfile geotagged posts, the date filter cuts it off, or the 200-page scan cap is hit. With it off, every scanned post is kept, geotagged or not.

Does this work with Claude, ChatGPT, and AI agent frameworks?

It runs as a standard Apify Actor reachable over the Apify API, so any agent framework that can make an HTTP call or use the apify-client package can trigger a run and read the resulting dataset — there is no dedicated MCP server documented for this Actor.

Can I use it without an Instagram account or login?

Yes. No sessionId or Instagram credentials are required anywhere in the input — the Actor only needs profileUrls/startUrls and, optionally, proxyConfiguration.

What's the difference between profileUrls/postsPerProfile and startUrls/maxPosts?

startUrls and maxPosts are legacy field names kept so input JSON built for the base Instagram Posts Scraper still runs unchanged. profileUrls and postsPerProfile are the current names; if both a current and legacy field are set, the current one wins.

Conclusion

Instagram Posts Scraper With Tagged Places & Coordinates turns a plain post export into structured, mappable location data — every post carries a hasLocation flag and a parsed taggedPlace object instead of Instagram's raw, undocumented location payload, and a per-profile roll-up surfaces a creator's most-tagged places without any manual counting. It's built for travel and hospitality marketers, agencies auditing multiple accounts, and researchers mapping geotagging activity across profiles. Run it from the Apify Console or trigger it through the API with profileUrls and onlyGeotagged set to get straight to geotagged results.