insta-collect-data 0.2.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,313 @@
1
+ Metadata-Version: 2.4
2
+ Name: insta-collect-data
3
+ Version: 0.2.0
4
+ Summary: Modular Instagram Data Collector
5
+ Author-email: Alam Mahadika <alam.mahadika.psm@umy.ac.id>
6
+ License: MIT
7
+ Project-URL: Homepage, https://github.com/Alammahadika/insta-collect
8
+ Keywords: instagram,scraper,hashtag,profile,engagement,analytics,comments
9
+ Requires-Python: >=3.10
10
+ Description-Content-Type: text/markdown
11
+ Requires-Dist: beautifulsoup4>=4.12.2
12
+ Requires-Dist: lxml>=4.9.3
13
+ Requires-Dist: pandas>=2.1.0
14
+ Requires-Dist: openpyxl>=3.1.2
15
+ Requires-Dist: requests>=2.31.0
16
+ Requires-Dist: tqdm>=4.65.0
17
+ Requires-Dist: playwright>=1.40.0
18
+
19
+ # insta-collect-data: Modular Instagram Data Collector
20
+
21
+ ## Project Status: In Development
22
+
23
+ insta-collect-data is a Playwright-based collector for Instagram **hashtags** and **profiles**. It supports photo and carousel posts as well as Reels, extracts post-level engagement metrics, and can compute per-profile engagement rates for influencer research.
24
+
25
+ The live scraper is functional but depends on Instagram's public markup. Expect occasional breakage when Instagram changes its HTML or tightens its login wall. The HTML comment parser is still experimental.
26
+
27
+ ***
28
+
29
+ ## Project Overview
30
+
31
+ insta-collect-data is a small, modular Python project that automates Instagram in a real browser via **Playwright**. It is intended for structured data collection for analysis and research: hashtag sampling, creator profiling, engagement comparisons, and small-batch archival work.
32
+
33
+ ***
34
+
35
+ ## Current Key Features
36
+
37
+ * **Hashtag Scraping:** Collect posts from an explore/tag page.
38
+ * **Profile Scraping:** Collect recent posts for one handle or a list of handles in a single browser session.
39
+ * **Engagement Metrics:** Extract `likes`, `comments`, and `views` (when Instagram exposes them), plus profile `followers`, `following`, and total `posts`.
40
+ * **Engagement Rate:** Compute average engagement per post and ER% for each scraped profile.
41
+ * **Reels Included:** Both `/p/` posts and `/reel/` links are collected. Older versions filtered videos out; that is no longer the case.
42
+ * **Rich Post Data:** `url`, `username`, `caption`, `caption_status`, `timestamp`, `is_video`, `hashtags`, `mentions`, `likes`, `comments`, `views`.
43
+ * **Session Reuse:** Log in once with a visible browser and reuse the saved Playwright profile on later headless runs.
44
+ * **Login-Wall Handling:** Detects Instagram login walls, dismisses cookie/sign-up modals when possible, and gives an actionable error in headless mode.
45
+ * **Dual Output:** Every run writes both **JSON** and **CSV**.
46
+ * **HTML Comment Extraction:** Parse comments from a previously saved Instagram HTML page into JSON and XLSX.
47
+
48
+ ***
49
+
50
+ ## Installation
51
+
52
+ ```bash
53
+ pip install insta-collect-data
54
+ ```
55
+
56
+ ### or install directly from GitHub
57
+
58
+ ```bash
59
+ pip install git+https://github.com/Alammahadika/insta-collect.git
60
+ ```
61
+
62
+ This distribution installs the `insta_collect` Python package and the `insta-collect` CLI command.
63
+
64
+ > `insta-collect-data` is the continuation of the earlier `insta-collect` package (last release 0.1.2) under a new PyPI name.
65
+
66
+ Requirements: **Python 3.10+** and a Chromium browser for Playwright.
67
+
68
+ ### Playwright Setup (Required)
69
+
70
+ Install the browser binaries once after installing the package:
71
+
72
+ ```bash
73
+ playwright install chromium
74
+ ```
75
+
76
+ ### First-Time Login (Recommended)
77
+
78
+ Instagram often blocks logged-out scraping with a login wall. Log in once using a visible browser; the session is stored in the Playwright profile directory (`ig_profile` by default) and reused afterwards.
79
+
80
+ ```bash
81
+ insta-collect --user natgeo --limit 6 --headed
82
+ ```
83
+
84
+ Log in manually in the window that opens, then let the run finish. Later runs work headless by default.
85
+
86
+ > Do not commit the `ig_profile/` folder — it contains your authenticated session.
87
+
88
+ ***
89
+
90
+ ## Usage
91
+
92
+ The installed CLI is `insta-collect`. It has two modes, and they are mutually exclusive.
93
+
94
+ ### Arguments
95
+
96
+ | Argument | Description | Default |
97
+ |---|---|---|
98
+ | `--tag` | Hashtag to scrape (without `#`) | — |
99
+ | `--user` | One handle, or a comma-separated list (`natgeo,nasa`) | — |
100
+ | `--users-file` | Text file with one handle per line; `#` starts a comment | — |
101
+ | `--limit` | Max posts per target (6–12 is a good range for engagement analysis) | `10` |
102
+ | `--profile` | Playwright persistent profile directory (session storage) | `ig_profile` |
103
+ | `--headed` | Show the browser window (first-time login / debugging) | headless |
104
+
105
+ Provide either `--tag` **or** `--user` / `--users-file`.
106
+
107
+ ### Hashtag mode
108
+
109
+ ```bash
110
+ insta-collect --tag donaldtrump --limit 10
111
+ ```
112
+
113
+ ### Single profile
114
+
115
+ ```bash
116
+ insta-collect --user natgeo --limit 10
117
+ ```
118
+
119
+ ### Multiple profiles
120
+
121
+ ```bash
122
+ insta-collect --user natgeo,nasa --limit 8
123
+ ```
124
+
125
+ Or from a file (`handles.txt`):
126
+
127
+ ```text
128
+ # one handle per line
129
+ natgeo
130
+ nasa
131
+ @somecreator
132
+ ```
133
+
134
+ ```bash
135
+ insta-collect --users-file handles.txt --limit 8
136
+ ```
137
+
138
+ ### Visible browser
139
+
140
+ ```bash
141
+ insta-collect --tag donaldtrump --limit 10 --headed
142
+ ```
143
+
144
+ ***
145
+
146
+ ## Output
147
+
148
+ Each run writes two files in the current directory.
149
+
150
+ | Mode | Files |
151
+ |---|---|
152
+ | Hashtag | `result_<tag>.json`, `result_<tag>.csv` |
153
+ | Single profile | `result_<handle>.json`, `result_<handle>.csv` |
154
+ | Multiple profiles | `result_profiles.json`, `result_profiles.csv` |
155
+
156
+ ### Post fields (hashtag mode)
157
+
158
+ ```json
159
+ [
160
+ {
161
+ "url": "https://www.instagram.com/p/DS3UWMfCRA5/",
162
+ "username": "cdn37",
163
+ "caption": "El presidente de Estados Unidos...",
164
+ "caption_status": "long_text",
165
+ "timestamp": "2025-12-29T22:35:50.000Z",
166
+ "is_video": false,
167
+ "hashtags": ["CDN", "Noticias", "DonaldTrump"],
168
+ "mentions": [],
169
+ "likes": 1200,
170
+ "comments": 34,
171
+ "views": null,
172
+ "source_tag": "donaldtrump"
173
+ }
174
+ ]
175
+ ```
176
+
177
+ `caption_status` is one of `long_text`, `short_text`, `no_text`, `login_required`, or `error`.
178
+
179
+ ### Profile fields (profile mode)
180
+
181
+ ```json
182
+ [
183
+ {
184
+ "handle": "natgeo",
185
+ "url": "https://www.instagram.com/natgeo/",
186
+ "followers": 283000000,
187
+ "following": 120,
188
+ "posts_total": 31000,
189
+ "posts_scraped": 8,
190
+ "avg_engagement": 45210.5,
191
+ "engagement_rate_pct": 0.016,
192
+ "posts": [
193
+ {
194
+ "url": "https://www.instagram.com/p/...",
195
+ "username": "natgeo",
196
+ "caption": "...",
197
+ "likes": 40000,
198
+ "comments": 5210,
199
+ "views": null,
200
+ "source_handle": "natgeo"
201
+ }
202
+ ]
203
+ }
204
+ ]
205
+ ```
206
+
207
+ ### Engagement rate definition
208
+
209
+ For each scraped post, engagement is `likes + comments`, plus `views` when that post reported a view count. Then:
210
+
211
+ ```text
212
+ avg_engagement = mean(per-post engagement)
213
+ engagement_rate_% = avg_engagement / followers * 100
214
+ ```
215
+
216
+ Instagram displays rounded counts (`12K`, `1.5M`), so parsed metrics are approximations, not exact values.
217
+
218
+ ### CSV note
219
+
220
+ CSV output is flat. In profile mode the nested `posts` list is written as a single serialized cell per profile. Use the JSON file when you need post-level analysis.
221
+
222
+ ***
223
+
224
+ ## How It Works
225
+
226
+ 1. **Session resumption:** Opens Chromium with the persistent `--profile` directory, reusing any saved login.
227
+ 2. **Link collection:** Navigates to the hashtag or profile page, dismisses the cookie banner, and scrolls until enough `/p/` and `/reel/` links are found (query strings stripped, duplicates removed).
228
+ 3. **Post extraction:** Visits each post, closes the sign-up modal when present, and reads `og:description` plus page selectors for caption, username, timestamp, and engagement metrics.
229
+ 4. **Filtering:** Skips posts that hit a login wall or throw an error. Reels and videos are kept.
230
+ 5. **Aggregation:** In profile mode, computes average engagement and ER% from the scraped posts.
231
+ 6. **Export:** Writes JSON and CSV.
232
+
233
+ ***
234
+
235
+ ## Limitations
236
+
237
+ * Instagram's login wall is the most common failure. If a headless run reports it, rerun once with `--headed` and log in.
238
+ * Logged-out hashtag grids often expose only Reels; results may be Reel-heavy.
239
+ * Metrics are rounded by Instagram (`K`/`M`/`B`) and may be missing entirely.
240
+ * Keep `--limit` modest and expect random delays between requests. This is not a high-volume crawler.
241
+ * The persistent profile directory contains credentials; exclude it from version control.
242
+
243
+ ***
244
+
245
+ ## Naming Conventions: `_` vs `-` in Python Projects
246
+
247
+ | Context | Use | Example |
248
+ |---|---|---|
249
+ | Package name (PyPI / GitHub) | `-` (hyphen) | insta-collect-data |
250
+ | Python package directory | `_` (underscore) | insta_collect |
251
+ | Python import statement | `_` (underscore) | import insta_collect |
252
+ | CLI execution via module | `_` (underscore) | python -m insta_collect.cli |
253
+ | Script / file name | flexible | insta-collect.py |
254
+
255
+ ***
256
+
257
+ ## Collecting Comments from an HTML File
258
+
259
+ In addition to live scraping, insta-collect-data can parse comments from a saved Instagram HTML page made in a logged-in browser.
260
+
261
+ This is useful when:
262
+
263
+ * You already saved the page and want structured comments.
264
+ * You want to avoid live requests.
265
+ * You need an XLSX deliverable.
266
+
267
+ ### Example
268
+
269
+ ```bash
270
+ cd path/to/insta_collect # the package directory in a repo checkout
271
+ python3 insta-collect.py ~/Downloads/obama.html --preview 20
272
+ ```
273
+
274
+ The script writes `instagram_comments.json` and `instagram_comments.xlsx` to the current directory.
275
+
276
+ ### Output
277
+
278
+ ```text
279
+ [+] Total entries saved: 239
280
+ [+] JSON output: instagram_comments.json
281
+ [+] XLSX output: instagram_comments.xlsx
282
+ ```
283
+
284
+ ### Comment fields
285
+
286
+ * `username`
287
+ * `text` (`comment_text` in the README of older releases)
288
+ * `timestamp` when available
289
+ * `source_file`
290
+
291
+ ### Notes
292
+
293
+ * Output filenames are fixed; existing files are overwritten.
294
+ * `--preview` only affects terminal output, not the saved data.
295
+ * This feature is experimental and may change.
296
+
297
+ ***
298
+
299
+ ## Roadmap
300
+
301
+ * Live comment scraping.
302
+ * XLSX export for live post/profile runs.
303
+ * Retry/backoff and proxy support for larger batches.
304
+ * Optional pagination beyond the recent grid.
305
+
306
+ Completed in this release: profile scraping, engagement metrics/ER%, CSV output, Reels support, headless-by-default with persistent login.
307
+
308
+ ***
309
+
310
+ ## Ethical Use Notice
311
+
312
+ This tool is intended strictly for academic research, journalism, and public-interest analysis.
313
+ Users are responsible for complying with Instagram's Terms of Service and applicable laws.
@@ -0,0 +1,295 @@
1
+ # insta-collect-data: Modular Instagram Data Collector
2
+
3
+ ## Project Status: In Development
4
+
5
+ insta-collect-data is a Playwright-based collector for Instagram **hashtags** and **profiles**. It supports photo and carousel posts as well as Reels, extracts post-level engagement metrics, and can compute per-profile engagement rates for influencer research.
6
+
7
+ The live scraper is functional but depends on Instagram's public markup. Expect occasional breakage when Instagram changes its HTML or tightens its login wall. The HTML comment parser is still experimental.
8
+
9
+ ***
10
+
11
+ ## Project Overview
12
+
13
+ insta-collect-data is a small, modular Python project that automates Instagram in a real browser via **Playwright**. It is intended for structured data collection for analysis and research: hashtag sampling, creator profiling, engagement comparisons, and small-batch archival work.
14
+
15
+ ***
16
+
17
+ ## Current Key Features
18
+
19
+ * **Hashtag Scraping:** Collect posts from an explore/tag page.
20
+ * **Profile Scraping:** Collect recent posts for one handle or a list of handles in a single browser session.
21
+ * **Engagement Metrics:** Extract `likes`, `comments`, and `views` (when Instagram exposes them), plus profile `followers`, `following`, and total `posts`.
22
+ * **Engagement Rate:** Compute average engagement per post and ER% for each scraped profile.
23
+ * **Reels Included:** Both `/p/` posts and `/reel/` links are collected. Older versions filtered videos out; that is no longer the case.
24
+ * **Rich Post Data:** `url`, `username`, `caption`, `caption_status`, `timestamp`, `is_video`, `hashtags`, `mentions`, `likes`, `comments`, `views`.
25
+ * **Session Reuse:** Log in once with a visible browser and reuse the saved Playwright profile on later headless runs.
26
+ * **Login-Wall Handling:** Detects Instagram login walls, dismisses cookie/sign-up modals when possible, and gives an actionable error in headless mode.
27
+ * **Dual Output:** Every run writes both **JSON** and **CSV**.
28
+ * **HTML Comment Extraction:** Parse comments from a previously saved Instagram HTML page into JSON and XLSX.
29
+
30
+ ***
31
+
32
+ ## Installation
33
+
34
+ ```bash
35
+ pip install insta-collect-data
36
+ ```
37
+
38
+ ### or install directly from GitHub
39
+
40
+ ```bash
41
+ pip install git+https://github.com/Alammahadika/insta-collect.git
42
+ ```
43
+
44
+ This distribution installs the `insta_collect` Python package and the `insta-collect` CLI command.
45
+
46
+ > `insta-collect-data` is the continuation of the earlier `insta-collect` package (last release 0.1.2) under a new PyPI name.
47
+
48
+ Requirements: **Python 3.10+** and a Chromium browser for Playwright.
49
+
50
+ ### Playwright Setup (Required)
51
+
52
+ Install the browser binaries once after installing the package:
53
+
54
+ ```bash
55
+ playwright install chromium
56
+ ```
57
+
58
+ ### First-Time Login (Recommended)
59
+
60
+ Instagram often blocks logged-out scraping with a login wall. Log in once using a visible browser; the session is stored in the Playwright profile directory (`ig_profile` by default) and reused afterwards.
61
+
62
+ ```bash
63
+ insta-collect --user natgeo --limit 6 --headed
64
+ ```
65
+
66
+ Log in manually in the window that opens, then let the run finish. Later runs work headless by default.
67
+
68
+ > Do not commit the `ig_profile/` folder — it contains your authenticated session.
69
+
70
+ ***
71
+
72
+ ## Usage
73
+
74
+ The installed CLI is `insta-collect`. It has two modes, and they are mutually exclusive.
75
+
76
+ ### Arguments
77
+
78
+ | Argument | Description | Default |
79
+ |---|---|---|
80
+ | `--tag` | Hashtag to scrape (without `#`) | — |
81
+ | `--user` | One handle, or a comma-separated list (`natgeo,nasa`) | — |
82
+ | `--users-file` | Text file with one handle per line; `#` starts a comment | — |
83
+ | `--limit` | Max posts per target (6–12 is a good range for engagement analysis) | `10` |
84
+ | `--profile` | Playwright persistent profile directory (session storage) | `ig_profile` |
85
+ | `--headed` | Show the browser window (first-time login / debugging) | headless |
86
+
87
+ Provide either `--tag` **or** `--user` / `--users-file`.
88
+
89
+ ### Hashtag mode
90
+
91
+ ```bash
92
+ insta-collect --tag donaldtrump --limit 10
93
+ ```
94
+
95
+ ### Single profile
96
+
97
+ ```bash
98
+ insta-collect --user natgeo --limit 10
99
+ ```
100
+
101
+ ### Multiple profiles
102
+
103
+ ```bash
104
+ insta-collect --user natgeo,nasa --limit 8
105
+ ```
106
+
107
+ Or from a file (`handles.txt`):
108
+
109
+ ```text
110
+ # one handle per line
111
+ natgeo
112
+ nasa
113
+ @somecreator
114
+ ```
115
+
116
+ ```bash
117
+ insta-collect --users-file handles.txt --limit 8
118
+ ```
119
+
120
+ ### Visible browser
121
+
122
+ ```bash
123
+ insta-collect --tag donaldtrump --limit 10 --headed
124
+ ```
125
+
126
+ ***
127
+
128
+ ## Output
129
+
130
+ Each run writes two files in the current directory.
131
+
132
+ | Mode | Files |
133
+ |---|---|
134
+ | Hashtag | `result_<tag>.json`, `result_<tag>.csv` |
135
+ | Single profile | `result_<handle>.json`, `result_<handle>.csv` |
136
+ | Multiple profiles | `result_profiles.json`, `result_profiles.csv` |
137
+
138
+ ### Post fields (hashtag mode)
139
+
140
+ ```json
141
+ [
142
+ {
143
+ "url": "https://www.instagram.com/p/DS3UWMfCRA5/",
144
+ "username": "cdn37",
145
+ "caption": "El presidente de Estados Unidos...",
146
+ "caption_status": "long_text",
147
+ "timestamp": "2025-12-29T22:35:50.000Z",
148
+ "is_video": false,
149
+ "hashtags": ["CDN", "Noticias", "DonaldTrump"],
150
+ "mentions": [],
151
+ "likes": 1200,
152
+ "comments": 34,
153
+ "views": null,
154
+ "source_tag": "donaldtrump"
155
+ }
156
+ ]
157
+ ```
158
+
159
+ `caption_status` is one of `long_text`, `short_text`, `no_text`, `login_required`, or `error`.
160
+
161
+ ### Profile fields (profile mode)
162
+
163
+ ```json
164
+ [
165
+ {
166
+ "handle": "natgeo",
167
+ "url": "https://www.instagram.com/natgeo/",
168
+ "followers": 283000000,
169
+ "following": 120,
170
+ "posts_total": 31000,
171
+ "posts_scraped": 8,
172
+ "avg_engagement": 45210.5,
173
+ "engagement_rate_pct": 0.016,
174
+ "posts": [
175
+ {
176
+ "url": "https://www.instagram.com/p/...",
177
+ "username": "natgeo",
178
+ "caption": "...",
179
+ "likes": 40000,
180
+ "comments": 5210,
181
+ "views": null,
182
+ "source_handle": "natgeo"
183
+ }
184
+ ]
185
+ }
186
+ ]
187
+ ```
188
+
189
+ ### Engagement rate definition
190
+
191
+ For each scraped post, engagement is `likes + comments`, plus `views` when that post reported a view count. Then:
192
+
193
+ ```text
194
+ avg_engagement = mean(per-post engagement)
195
+ engagement_rate_% = avg_engagement / followers * 100
196
+ ```
197
+
198
+ Instagram displays rounded counts (`12K`, `1.5M`), so parsed metrics are approximations, not exact values.
199
+
200
+ ### CSV note
201
+
202
+ CSV output is flat. In profile mode the nested `posts` list is written as a single serialized cell per profile. Use the JSON file when you need post-level analysis.
203
+
204
+ ***
205
+
206
+ ## How It Works
207
+
208
+ 1. **Session resumption:** Opens Chromium with the persistent `--profile` directory, reusing any saved login.
209
+ 2. **Link collection:** Navigates to the hashtag or profile page, dismisses the cookie banner, and scrolls until enough `/p/` and `/reel/` links are found (query strings stripped, duplicates removed).
210
+ 3. **Post extraction:** Visits each post, closes the sign-up modal when present, and reads `og:description` plus page selectors for caption, username, timestamp, and engagement metrics.
211
+ 4. **Filtering:** Skips posts that hit a login wall or throw an error. Reels and videos are kept.
212
+ 5. **Aggregation:** In profile mode, computes average engagement and ER% from the scraped posts.
213
+ 6. **Export:** Writes JSON and CSV.
214
+
215
+ ***
216
+
217
+ ## Limitations
218
+
219
+ * Instagram's login wall is the most common failure. If a headless run reports it, rerun once with `--headed` and log in.
220
+ * Logged-out hashtag grids often expose only Reels; results may be Reel-heavy.
221
+ * Metrics are rounded by Instagram (`K`/`M`/`B`) and may be missing entirely.
222
+ * Keep `--limit` modest and expect random delays between requests. This is not a high-volume crawler.
223
+ * The persistent profile directory contains credentials; exclude it from version control.
224
+
225
+ ***
226
+
227
+ ## Naming Conventions: `_` vs `-` in Python Projects
228
+
229
+ | Context | Use | Example |
230
+ |---|---|---|
231
+ | Package name (PyPI / GitHub) | `-` (hyphen) | insta-collect-data |
232
+ | Python package directory | `_` (underscore) | insta_collect |
233
+ | Python import statement | `_` (underscore) | import insta_collect |
234
+ | CLI execution via module | `_` (underscore) | python -m insta_collect.cli |
235
+ | Script / file name | flexible | insta-collect.py |
236
+
237
+ ***
238
+
239
+ ## Collecting Comments from an HTML File
240
+
241
+ In addition to live scraping, insta-collect-data can parse comments from a saved Instagram HTML page made in a logged-in browser.
242
+
243
+ This is useful when:
244
+
245
+ * You already saved the page and want structured comments.
246
+ * You want to avoid live requests.
247
+ * You need an XLSX deliverable.
248
+
249
+ ### Example
250
+
251
+ ```bash
252
+ cd path/to/insta_collect # the package directory in a repo checkout
253
+ python3 insta-collect.py ~/Downloads/obama.html --preview 20
254
+ ```
255
+
256
+ The script writes `instagram_comments.json` and `instagram_comments.xlsx` to the current directory.
257
+
258
+ ### Output
259
+
260
+ ```text
261
+ [+] Total entries saved: 239
262
+ [+] JSON output: instagram_comments.json
263
+ [+] XLSX output: instagram_comments.xlsx
264
+ ```
265
+
266
+ ### Comment fields
267
+
268
+ * `username`
269
+ * `text` (`comment_text` in the README of older releases)
270
+ * `timestamp` when available
271
+ * `source_file`
272
+
273
+ ### Notes
274
+
275
+ * Output filenames are fixed; existing files are overwritten.
276
+ * `--preview` only affects terminal output, not the saved data.
277
+ * This feature is experimental and may change.
278
+
279
+ ***
280
+
281
+ ## Roadmap
282
+
283
+ * Live comment scraping.
284
+ * XLSX export for live post/profile runs.
285
+ * Retry/backoff and proxy support for larger batches.
286
+ * Optional pagination beyond the recent grid.
287
+
288
+ Completed in this release: profile scraping, engagement metrics/ER%, CSV output, Reels support, headless-by-default with persistent login.
289
+
290
+ ***
291
+
292
+ ## Ethical Use Notice
293
+
294
+ This tool is intended strictly for academic research, journalism, and public-interest analysis.
295
+ Users are responsible for complying with Instagram's Terms of Service and applicable laws.