My Cron Pipeline Drafts Through a Browser, With Local Backup
Free Qwen chat via Playwright is now the primary draft engine for my article cron, with a local router9 fallback wired like a circuit breaker.
TL;DR
Pipeline cron pakai lane gratis Qwen lewat Playwright yang memutar UI chat, lalu menyalin jawaban via clipboard karena jawaban panjang tak utuh di DOM. Untuk antisipasi matinya free tier, dipasang fallback router9 lokal dengan pola circuit breaker. Dua lane ini gagal karena penyebab berbeda, jadi fallback benar-benar berfungsi sebagai asuransi.
The draft prompt goes out, and the tab that comes back is a chat window. No API key, no endpoint, no JSON. Just Qwen's web chat, driven by a Playwright script, with my local router9 model waiting in the wings for the moment it all falls apart. That's the new lane for draft generation in my cron article pipeline, and I want to walk through why it looks this stupid on purpose.
The free lane has no door
Qwen's chat tier is free, and free means there's no official API path. If I want the model's output, I have to go through the same UI a human uses. So the script opens the page with Playwright on top of Camoufox, types the prompt, waits for the answer to finish streaming, and then does the part I'm least proud of and most attached to: it copies the answer to the clipboard and reads it from there.
Why not just grab the DOM? Because long answers don't fully exist in it. Qwen renders them in a virtualized window, so the tail of a long reply is never in the tree. The clipboard copy is the one path that always returns the whole thing. It's a hack that survives because it leans on a feature the UI promises to users, not on internals the UI promises to nobody.
That's also the honest weakness. Any redesign of the chat page breaks the script overnight. Selectors rot, buttons move, and the cycle burns its retry budget on a page I no longer recognize. I've accepted this. The question was never "how do I make scraping permanent" but "what happens the day it dies," because with free tiers, that day is a matter of when.
Free tiers die loudly
It's not paranoia, it's recent history. The qwen-code project had its OAuth free quota cut from one thousand requests per day to one hundred, and then the free entry point was closed entirely [5]. Thousands of people built workflows on that quota. Nobody got a vote. And the ToS says the quiet part out loud: Qwen can restrict the service without notice and without explanation [4]. So a lane that depends on their goodwill is a lane with a fuse.
My answer is router9, a local model, as fallback. The routing follows the circuit breaker pattern: Microsoft's Azure Architecture Center describes it as temporarily blocking calls to a service that is likely to fail once failures hit a threshold, instead of retrying endlessly [1]. In practice: fail fast, at most one retry against Qwen, and after two consecutive failures the rest of the cycle routes straight to router9. No hammering a service that's already angry at me, no half-hour of retries burning the cron window. The breaker trips, the cycle finishes on local hardware, and next cycle it tries Qwen again from a clean slate.
The part that makes this actually worth doing is that the two lanes fail for different reasons. It is the same thinking behind my failure-proof research script with two-provider key rotation: never rest a working lane on a single point of failure. A fallback inside the same provider doesn't help when the provider itself goes down; WSO2's writeup on fallback strategies makes exactly this point [2]. Qwen's web lane dies from UI changes, quota cuts, and ToS enforcement. Router9 dies when my GPU dies. Different failure domains mean the fallback is real insurance, not the same bet placed twice.
Playwright as a frontend mirror
One side effect I didn't plan: driving my own reading habits through a browser taught me things about frontend quality I'd normally only feel as a user. Every time Qwen ships a change that breaks my script, that's a regression in someone's frontend hygiene. Unstable selectors, unlabeled buttons, layout thrash mid-stream. A page that works well for automation is usually just a page that works well, full stop. Playwright documentation pitches it as reliable automation for modern web apps, and reliability is exactly what it audits [3].
Where does this leave the pipeline? Two lanes, no illusions. Qwen's chat is the free primary, and I expect it to get worse. Router9 is the paid-in-electricity backup that answers whether I like the quality or not. The design bet isn't that scraping lasts. It's that the pipeline keeps running when it doesn't.
---
Sources:
- Microsoft Azure Architecture Center, Circuit Breaker pattern [1]
- WSO2, LLM Fallback Strategies [2]
- Playwright Documentation [3]
- Qwen Terms of Service [4]
- Issue #3203, QwenLM/qwen-code (free tier policy adjustment) [5]
[1] https://learn.microsoft.com/en-us/azure/architecture/patterns/circuit-breaker [2] https://wso2.com/api-platform/learn/llm-fallback-strategies [3] https://playwright.dev/docs/intro [4] https://qwen.ai/termsservice [5] https://github.com/QwenLM/qwen-code/issues/3203