tooling: instagram-chrome-scrape.py (was reels-scrape.py) gains --tab posts with early stop; chrome-sync.sh + reels/posts-sync.sh wrappers; MANUAL-RUN.md; atomic-deploy note
This commit is contained in:
+46
-7
@@ -23,6 +23,9 @@
|
||||
|
||||
## Quick reference — getting new content onto the site
|
||||
|
||||
For the whole thing by hand, step by step (including the DH2300 / `cosmo_web` hop), see
|
||||
[MANUAL-RUN.md](MANUAL-RUN.md).
|
||||
|
||||
The three systemd timers (see "Scheduling" below) run these unattended; run
|
||||
them by hand only to get content sooner. Everything runs on `mattellite`; it
|
||||
fetches, publishes to the NAS itself, and the site picks it up with no deploy
|
||||
@@ -290,8 +293,11 @@ restored, `posts` listings for `heejin`/`kimxxlip` returned `No results` in ~3 s
|
||||
profile skips; it does not say that), while stories worked and the posts opened fine in the
|
||||
browser. The host was on gallery-dl 1.32.14; 1.32.17 (2026-10-17) lists "instagram: update
|
||||
`user` & `posts` query parameters". After upgrading, the profile lookup failed instead
|
||||
(`KeyError: 'data'`, `Requested user could not be found`) -- **unresolved when written**, see
|
||||
the end of this section.
|
||||
(`KeyError: 'data'`, `Requested user could not be found`). That is upstream
|
||||
[gh#9829](https://github.com/mikf/gallery-dl/issues/9829) -- Instagram changed the query again
|
||||
on ~10-21; a fix is merged upstream but **not in a release** as of 10-22. Single-post fetches
|
||||
(`/p/<code>/`) still work, so the gap is the *listing*, which the browser covers -- see
|
||||
"Posts grid by browser" below.
|
||||
|
||||
`scripts/gdl-upgrade.sh` (`pipx upgrade --include-injected gallery-dl`, so yt-dlp too) now runs:
|
||||
|
||||
@@ -303,6 +309,35 @@ the end of this section.
|
||||
It costs no Instagram requests. The trade-off: a bad upstream release is picked up
|
||||
automatically; roll back with `pipx install --force gallery-dl==<old>` and re-inject yt-dlp.
|
||||
|
||||
### Posts grid by browser: `posts-sync.sh`
|
||||
|
||||
The reels workaround from August, generalised. `reels-scrape.py` is now
|
||||
**`instagram-chrome-scrape.py`** with `--tab reels|posts`, and `reels-sync.sh`'s body is now
|
||||
**`chrome-sync.sh`** (`GDL_TAB=reels|posts`); `reels-sync.sh` and the new `posts-sync.sh` are
|
||||
two-line wrappers that set the tab, so every older command still works.
|
||||
|
||||
```sh
|
||||
ssh mattellite
|
||||
~/gdl/posts-sync.sh heejin # scroll /heejin/, fetch new /p/ links as single posts
|
||||
```
|
||||
|
||||
`--tab posts` scrolls the main grid (`/<user>/`), collects `/p/` and `/reel/` links, and dedupes
|
||||
against the whole archive like the reels tab does. Unlike reels it **stops early**: the grid is
|
||||
newest-first, so after 2 scroll rounds in a row that turned up nothing unarchived
|
||||
(`--max-known-rounds`, round 1 exempt because pinned posts sit on top) there is nothing newer to
|
||||
find. First run, `heejin`: 3 scrolls, 36 posts seen, 30 already held, 6 new.
|
||||
|
||||
Same caveats as reels: it drives the signed-in Chrome on `:9222`, so it is by hand, not on a
|
||||
timer. Once a gallery-dl release fixes the listing, `run-profiles.sh` covers posts again and
|
||||
this goes back to being a fallback.
|
||||
|
||||
**Deploy scripts atomically, never in place.** bash reads a script as it runs, so overwriting
|
||||
`gdl-cron.sh` under a running sync makes bash resume at the same byte offset in the *new* text.
|
||||
On 10-22 an `scp` over it mid-run made the wrapper die after the sync with
|
||||
`line 163: status: unbound variable`. The fetch and publish had finished, but the exit line and
|
||||
the Healthchecks ping were skipped. Copy to a temp name and `mv` it into place (a new inode; the
|
||||
running bash keeps the old one), or check `pgrep -af gdl-` first.
|
||||
|
||||
**A `--min-interval` trap:** a run that returns `No results` still counts as a fetch, so the
|
||||
next run skips the source for 20 h. Re-run after a bad result with `--min-interval 0`
|
||||
(not `--force`, which also drops the probe cache).
|
||||
@@ -339,6 +374,9 @@ every deletion because of it.
|
||||
| path | what it is |
|
||||
|---|---|
|
||||
| `scripts/gdl-sync.py` | the gallery-dl fetcher; replaced JD2 for the ARTMS profiles |
|
||||
| `scripts/gdl-upgrade.sh` | `pipx upgrade` gallery-dl + yt-dlp; run by `gdl-cron.sh` and `gdl-upgrade.timer` |
|
||||
| `scripts/instagram-chrome-scrape.py` | list a profile's reels tab or posts grid by scrolling the signed-in Chrome over CDP |
|
||||
| `scripts/chrome-sync.sh` | scrape + fetch new posts for one profile; `reels-sync.sh` / `posts-sync.sh` set the tab |
|
||||
| `scripts/gdl-cron.sh` | unattended wrapper: `stories` \| `profiles` \| `full-sweep` |
|
||||
| `scripts/systemd/` | the timers actually installed on the fetch host |
|
||||
| `scripts/test_gdl_sync.py` | its tests |
|
||||
@@ -746,7 +784,7 @@ before something worse.
|
||||
changelog cites "posts & reels extractors... content retrieval failures", and
|
||||
upgrading (`pipx upgrade gallery-dl`) confirmed it -- a full `run-profiles.sh`
|
||||
across all six profiles came back with **zero** `HTTP redirect` errors on
|
||||
posts or reels, first time since 2026-08-26. `reels-scrape.py`/`reels-sync.sh`/
|
||||
posts or reels, first time since 2026-08-26. `reels-scrape.py` (now `instagram-chrome-scrape.py`)/`reels-sync.sh`/
|
||||
`run-reels-all.sh` are no longer needed for routine use; left in place as a
|
||||
fallback (and because the whole-archive dedup fix they picked up along the
|
||||
way, see below, is independently useful). If this regresses, check the
|
||||
@@ -768,7 +806,8 @@ Posts, highlights and stories were unaffected at the time; only reels broke
|
||||
(posts later broke too, some time before 2026-09-13, in the same way — same
|
||||
fix resolved both).
|
||||
|
||||
`scripts/reels-scrape.py` works around it by never calling that endpoint:
|
||||
`scripts/reels-scrape.py` (renamed `instagram-chrome-scrape.py` on 2026-10-22, when it gained
|
||||
`--tab posts`) works around it by never calling that endpoint:
|
||||
it drives the same signed-in Chrome via its loopback CDP port (`:9222`,
|
||||
already exposed for MCP automation), scrolls the reels tab like a person
|
||||
would, and scrapes `/reel/<code>/` links out of the rendered page. It only
|
||||
@@ -841,7 +880,7 @@ PROFILE=someuser
|
||||
# 1. Scrape by scrolling; dedupe against the archive; write new URLs to a file.
|
||||
# Needs gallery-dl's own pipx venv python -- that's where websocket-client
|
||||
# (the one extra dependency this needs) got injected.
|
||||
~/.local/share/pipx/venvs/gallery-dl/bin/python3 ~/gdl/reels-scrape.py \
|
||||
~/.local/share/pipx/venvs/gallery-dl/bin/python3 ~/gdl/instagram-chrome-scrape.py \
|
||||
--profile "$PROFILE" \
|
||||
--index https://instaarchive.ergosteur.com \
|
||||
--out ~/gdl/"$PROFILE"-reels.txt
|
||||
@@ -857,7 +896,7 @@ cd ~/gdl && PATH=$HOME/.local/bin:$PATH ./gdl-sync.py \
|
||||
|
||||
Notes:
|
||||
|
||||
- `reels-scrape.py` fails fast if Chrome/CDP isn't up
|
||||
- `instagram-chrome-scrape.py` fails fast if Chrome/CDP isn't up
|
||||
(`curl -s http://localhost:9222/json/version` to check first).
|
||||
- If it finds nothing new, `gdl-sync.py --post-urls-file` refuses to run
|
||||
("no usable URLs") rather than doing nothing quietly — expected when a
|
||||
@@ -880,7 +919,7 @@ them, filed them correctly under `{username}` (the post's *true* owner, per
|
||||
its own metadata) — where they already existed from that profile's own
|
||||
regular sync — and `rsync --ignore-existing` silently skipped every one, so
|
||||
nothing was lost or duplicated. But 9 Instagram requests were spent finding
|
||||
that out. Since a shortcode is globally unique, `reels-scrape.py` now checks
|
||||
that out. Since a shortcode is globally unique, the scraper now checks
|
||||
every archived profile's listing, not just the one being scraped — all local
|
||||
requests to the viewer's own API, never to `instagram.com`, so checking all
|
||||
16 profiles costs nothing on the budget that actually matters. Confirmed
|
||||
|
||||
Reference in New Issue
Block a user