#!/usr/bin/env python3
"""Resolve Google News RSS links to real article URLs via scrapling stealthy-fetch."""
import subprocess, json, re, sys, os, time

GN_LINKS = [
    ("1. 最後一輪宏福苑聽證會今舉行（881903.com，07月15日）", "https://news.google.com/rss/articles/CBMiU0FVX3lxTFBNZnFCSzBiNjBkbFF5bUFleVFGcE5FVWwyQ3lRZmpjRWdOLXJhTFY1RHByWXZEdi1xZUg0S2tnWEJIX2o4b0xjVjVnTjcyLTJoVk9B0gFYQVVfeXFMTzdYNkg3WUhSaHRYQW9TS09EZ01QcFVjUlR"),
    ("2. 宏福苑聽證會揭各部門災前收大量投訴（Now新聞，07月13日）", "https://news.google.com/rss/articles/CBMiYkFVX3lxTFBUV19wVGpsZjVpQmE5LVB4ZUN2YXdvYWlubVB6UWhUd043a0xrRi1kNmlNYmJXYVZpS3FiMFdhZXoyQmJEM20zZTRoRVhVbTFhNkNLQXkyeGFmMVo2dDJtVUhR?oc=5"),
    ("3. 宏福苑聽證會｜中華發展：有火警鐘亦難逃生（Now新聞，07月15日）", "https://news.google.com/rss/articles/CBMiYkFVX3lxTE9idDlaeE1LSlhJWTMxMThpRTJ2NldsUXI5ZWpLcW1MWHItS1hGMFVweEhQUkxhN2JCenN2Q1hYeV9UQTZjbjdJRUlPb2N1aFYyb3RMZmZaLTk2bXBuSTNsaGpR?oc=5"),
    ("4. 採訪日誌｜地盤禁煙今日起實施（Now新聞，07月16日）", "https://news.google.com/rss/articles/CBMiYkFVX3lxTE1yNkt5WWlyMktvNDRxdXI5N1JPUkdKdUZ0d3dzc1FiLUNGYlZqUFowcVVDVEVQMnVWOHBCSVk2M0VJVk5TUkxsckpOUTRXUU9XYWNRY1JkekN6eU5iRTFmZll3?oc=5"),
    ("5. 宏福苑聽證會｜居民方總結陳詞批有人卸責（Now新聞，07月16日）", "https://news.google.com/rss/articles/CBMiYkFVX3lxTFBvS1pOSldYS01EZGhhbUJtaDZuN2d3YzRDU3VXTHpuLVdGLWlPNWVaV1VkN2ZVUHg0cVpNWTlVUDBIdlN0d2FvQk8zRElCTnhZZ09ESGZiVEhjTFN0YkFFRHZ3?oc=5"),
    ("6. 宏福苑聽證會｜居民方總結陳詞批有人卸責（Now新聞，07月16日）", "https://news.google.com/rss/articles/CBMiYkFVX3lxTFA2SjhCdlFOTHVWclF3Zml1QTNDbXNkYXhKRHR4M2pEZF9yb2pqdnJ4d1ZPc0gyRU9COUdzNlR3MXQ1dGxNZVlvQnJyMGptbGh4ZjBxbFNQa2I0QmhQa2VhVWdR?oc=5"),
    ("7. 宏福苑聽證會｜孫靖乾：宏業、鴻毅辜負政府信任（Now新聞，07月16日）", "https://news.google.com/rss/articles/CBMiYkFVX3lxTE8zSDYtQ1BPVUYyS25KSUpSYVdtYm9jRkh2RXhHaVNYT08xRnlZNkMyY09TZGFmOWVVaGtlN0VjbXFSYW5JMm13dDlTcGk5OTdYaFJxOXhwaXNGYTNqeHV2T3RB?oc=5"),
    ("8. 宏福苑聽證會各方總結（RTHK News，07月15日）", "https://news.google.com/rss/articles/CBMib0FVX3lxTE9SVG5kT0tjSWtGcC11NlBCUm5ZM3VOdTVQeDAzZ1R6aG1BTTU2VlVxWThMOU1HU1lGS2VfWm05NTk1bkdmTmJ5X3V6MlhVZ2owWEN3YkFPc2hnV2lyY2JoN3BHemVuUGRjbm1zdl95MA?oc=5"),
    ("9. 宏福苑聽證會繼續總結陳詞（RTHK News，07月16日）", "https://news.google.com/rss/articles/CBMib0FVX3lxTE94WjRoRm4zbzJIMmF5ZnltMHliT1o0UjM1ZFkxbVB4LUx0d05vby1xUE5SRDEzLWExd1JPQ09xWm5ZN3ljS21leGVlUU9JT0ZFMVB2UEotbjRCRUsyalg1UjhpLVB5NFh1b1Bjai1CRQ?oc=5"),
    ("10. 宏福苑聽證會揭示圍標問題（Singtaousa，07月15日）", "https://news.google.com/rss/articles/CBMijgFBVV95cUxPNXpHbWVEN0YxUVdoSG52RUN3emotRnluTlZ2QTkzWEpaa3ZReHBxVjFfMlNFaUNONkJPMl9BSXhxRkJtY2FqalFGWkRYLWg2N3FuQUw4d0pxSUxWSlJnYkUyc2pMUHZqcTVRV3pGYkNvX1g0Ym9"),
    ("11. 宏福苑大火聽證會政府總結陳詞（Singtaousa，07月16日）", "https://news.google.com/rss/articles/CBMiogFBVV95cUxPdEM2VXJycmc2MHBVMnBLZDFmYzNtQTNDUlo0SWU1dlZtRkYxU1JneS1wTERpZElIY1ZxVkFzYWZFcFZLczRpZGxZclhzQmc5ZGxCc2xzREZ5XzNqZjFvNDlfenlrM21ReEJkRnV3cWRSMWtpVGZ"),
    ("12. 宏福苑聽證會政府總結陳詞（Singtaousa，07月16日）", "https://news.google.com/rss/articles/CBMipAFBVV95cUxOSllVS2hFOF9LY1BwR2piM2hySUJBMVdaWGVkMjdpLXNHSlRWV3Q4bDNmZjQtbFhWRjBaLTIzaXJiLVlkNW5iWllva2gycy0zNUVtUHprMFpBXzcxbXVwWFVXdVQ1OEhYNVNtQ2diVkYwVTJuUml"),
    ("13. 宏福苑第六輪聽證會月中舉行（Yahoo，07月02日）", "https://news.google.com/rss/articles/CBMi9AJBVV95cUxNcE9VemdYQ1c5dWJ5Y3VhRUQwR2E3SHRXV2pQdmtsQmRwQ3ZGdGNfQWMtZVZxc1RNVWRzbGh4bkFpNDdfMFFLbUVqTC1hWTBCSjhObmFrWS05RnVjNHFBOGhOdnRJT29jSlIxc0dRVmsyWnRCcW9"),
    ("14. 宏福苑聽證會揭各部門災前收大量投訴（Yahoo，07月13日）", "https://news.google.com/rss/articles/CBMivgNBVV95cUxOSnJDRXRTY1BaaTlvcFo4RTU3SXFTVEF5VkhlZ3FsTV9wT0RRSlJTUktaWmVNZlliTnJZREJfT25oYmYwRlROOWVfX0RHY2o2NjZFcWt4Qy0xSnhIMV9EalBZQVBBOW5KQjJldVN5QmE2OFJzbkp"),
    ("15. 宏福苑聽證會｜競委會：有圍標由三合會領導（Yahoo，07月15日）", "https://news.google.com/rss/articles/CBMiiARBVV95cUxQUm05R2xzUWo0azRKNjdDMGRVb1BseE9ySEI5dWhqeGN2WE9rR19jZ1czaWtLeUhJNHAwUUUxZ0JZUV9nQ0t2MUtaWWNKYVBqU2ZGYjg3eVl0X0dLcEMzS2gyLW83N3lNLXhVZ2FkZnFGR0tPVF8"),
    ("16. 宏福苑聽證會｜置邦：大維修期間沒任何監督角色（Yahoo，07月15日）", "https://news.google.com/rss/articles/CBMizANBVV95cUxOMElmVVBtaDM4MmJfaTZRbmlBci1vVFRCWnVrTkVySy04MDVxSU1GcWExX0JVc1BxTS11cnRFYmE4OGhlXzFTOERmV3IwLW51OWhqLWdmd3JaLThVVzQ4cVpTS2NOSUkxbFFSS0xfVzBXd2cxOEx"),
    ("17. 晨早新聞重點｜宏福苑聽證會（Yahoo，07月16日）", "https://news.google.com/rss/articles/CBMi9ARBVV95cUxPSXlBYnFJS2NOSW05RFA5cXBVVVdwSWdmQlBoS3dZUTd2ZTJKTmVvODY1c2V6VkNWcTJMV25JOTUwbmZRc3hRWl9SVVJjNlRFaGh5aVRwcTZ2MndvY2Z1aUFxTUZmNU1JQUVYbUoxWXZUNXRiNlN"),
    ("18. 宏福苑聽證會｜居民方總結陳詞批有人卸責（Yahoo，07月16日）", "https://news.google.com/rss/articles/CBMi1wNBVV95cUxOZXlpNWZVcmM2Rm1tVHBTczVHOXZTQ1kybFZRcmloOV9rU2JaQmo1N0hfYUZrUUo2WUNvMzZENWphRmFNbjBBQ2V1XzZrYlJmUUp5ZXBuZHVQVl9tVUdadnZHQldHMkV1R3EtNGd5Y0tZM1NJM1I"),
    ("19. 宏福苑聽證會｜政府指承建商須負首要責任（Yahoo，07月16日）", "https://news.google.com/rss/articles/CBMivgNBVV95cUxNODcyTzJ6VHZxQmNvOFFiSVF0c2cyWE1ESFFDQ0pYbTc3ZjVtaGY2VllUbmRWRkFlaGY1a29weTVFX2ZUcm5yX1RtT0dVR0VMTVJ6MjBuM3lEaGFVZ3dRRVAxR2hCb0VDWWFoSC1WNGxZQlJCSU9"),
    ("20. 即日焦點｜宏福苑聽證會總結陳詞（Yahoo，07月16日）", "https://news.google.com/rss/articles/CBMiwwRBVV95cUxNbi1GdTNHbGlOWFV2Qm5adVMzck1wMDV6OVFfV2c2Qm1kTWlTaVhBWVFVeFdRUmtqRUhNbm1GSi1mREZFSkt6ckxlTWRpYUlYUUdpNTFRdmY4eGpXS3lKRVRpNkZrSWFoT25JRkh2YzZOSUc0TlA"),
    ("21. 聽證會｜宏福苑居民指政府有不可推卸責任（am730，07月16日）", "https://news.google.com/rss/articles/CBMi8gNBVV95cUxQa2NRcllLb3Z1S2pUZUVzQkc4cUJ6RzZlNW9NQ1p4dk5YN2taM3Nka2NFSmRqdkZYaW1hTmhSMkhOa2pDald6SDhMWHVPU2VaMGZHZzFtN2J5V0NIN2RPMldLS3JvZGR6aF9CazlONzA1bkdZT1o"),
    ("22. 香港宏福苑聽證會政府總結陳詞（hkcna.hk，07月16日）", "https://news.google.com/rss/articles/CBMiZkFVX3lxTE5lRldKS0Z4U29MQzZzYnNlZ3R6d2FPTVU4TXFiT2ZqSEZqY3lmQnNzTnozRGhNZDExQkswRVNRUlRZXzlsdGJIYWRXRW5ScC1RTFEyenpRVE5ZWmU2Nm1KN2dDTzA3UQ?oc=5"),
    ("23. 宏福苑大火獨委會總結陳詞（on.cc東網，07月17日）", "https://news.google.com/rss/articles/CBMiiwFBVV95cUxNcEE5VDRTcTRxbHkxR0RCQ093TFBRM1c0RjFWcEE4TlJ3cndLT3RmbjJVSXRmZEpDOG1qazFQaEtZT1hqTXhQUUFSdjJ5anFUSFctWlVfdHp1NHd1bGt3NzlKYnItUnRnQU9XQlp5MFZkclcxZFV"),
    ("24. 宏福苑聽證會｜最後一輪聽證會今舉行（singtao.ca，07月15日）", "https://news.google.com/rss/articles/CBMijAFBVV95cUxPaTFVa1VtN2JaMGhZME1XdTRncmQ1MGZCLXVpWEI2RXhyNXRiNEcyMDFsZWlRQ1FmWVZ4RG13ZTUzZ0dDMzNLNWhiYWlMb3VrbnkyVWpQUFhqbWV1SnpwdFFZRU1MTERSQk10YkdMaDRGeExUY0U"),
    ("25. 宏福苑聽證會｜政府代表總結陳詞（singtao.ca，07月16日）", "https://news.google.com/rss/articles/CBMivgRBVV95cUxNdXZNVVZhRDVYYWstZzMwX1FvNEdwdFF3YklPZDRWWW01ZDJzTWo1eWJ1cG95WDFpOUg5MmVCM0x0U3JqSEUwcEg1RHFRRzFndlo5MVdoM2sxRDUwS09hQUh5OTZEV2xqVzRua096YW1hXzlLSE5"),
    ("26. 宏福苑聽證會｜黃碧嬌工程前期扮演一定角色（singtao.ca，07月16日）", "https://news.google.com/rss/articles/CBMi7wRBVV95cUxQS1FpalpGOEFhMV9URC1xdlhUUHFjZjhHMmJZQjJyWjlVRWlxWTZGa3Q3LWNsVmw1dlNmZVpSanROOTlKOGkwTVB4QXpDUF9yU2IyS25RVnRzelJWcy1JS3EtYjNyNDk3bnZ0X0F4VE1QWXdseF9"),
    ("27. 宏福苑聽證會｜物管置邦斥宏泰消防董事供詞信口雌黃（信報網站，07月15日）", "https://news.google.com/rss/articles/CBMi_wJBVV95cUxPcXRLUTR3TnFFUFJrU0lTLUpVVEttOWdGTWFMNGl5eGp3MEdEMU52Mjl0eVhDcEZ2NnFMcTBqV3dKSXpkREZOVlpFRG9nN21kV2U4eEpOUHFaWVhRODNXZXBROWw2RF9BS3NTS08wSkRqeVJPcmV"),
    ("28. 宏福苑聽證會｜政府代表:專業人士及承建商蓄意違法（信報網站，07月16日）", "https://news.google.com/rss/articles/CBMiXkFVX3lxTE9QT0ROSUxvS2V6eHZwaFc4SEtmcFNRcDhIbzY3cEI0NVUwTU1wdzVVVGtKWDhXWTltOWxkcmozeGZIOHZLb3F3Q2FsVmhkLWxiVUhPSVRDbTlUVnFRcXc?oc=5"),
    ("29. 宏福苑聽證會｜最後一輪最後一場（信報網站，07月17日）", "https://news.google.com/rss/articles/CBMi9wJBVV95cUxPeXdOSGxZelhwN194aXllT2oteUZOLXd4NjR6VzJVWDljUXlPV0UtY2tEMlp6eGtEQUNWTHh2Z0ZnSXVyLWg5a3kwUnFPQ1JUYUFlY0F3TlY0VFZIaWIza05oZ3JLeElUdHpZSjhzT0pMbEJyUUx"),
    ("30. 宏福苑火災聽證會/政府大律師（，大公文匯網，07月16日）", "https://news.google.com/rss/articles/CBMidEFVX3lxTE8yd0dYMmhGRWNHZHpYNVdHVTVIMDgxYjkxWTJaeUJaTy1rSlExTWZXdTJaVFNObk4xSmRjVllJV2RYMUdQZFc3RzhkVUxPZ3poNUZwS3g0TW9wWHJrX1NhVDJZTlNPYlhhZ1pOUW4xb2dwRWMx?oc"),
    ("31. 強化監管/議員倡重新檢視行業指引（大公文匯網，07月16日）", "https://news.google.com/rss/articles/CBMidEFVX3lxTE9za3ZLekctc3hHVjJieXZYTHBKdFVGXzRvaEdPSVVhbWVLN0FXT291eGNMOG9VMUZoUFNYZHR6QWw5OWgzdUR0TXBLV3pETjB1bl9LSUxLc1hpSVdTVXBseGduUHQ5WFB1UXplWmRqa2h2V1pQ?oc"),
    ("32. 宏福苑五級火聽證會｜政府方陳詞（庭刊，07月16日）", "https://news.google.com/rss/articles/CBMixwJBVV95cUxObmtELVY0a1RZdlR0YWFGWDd5bVFYUXhLMGx0UE82dGR2NVhfLUJXYXZ6dGtUYURyQWktT2o2cFVxa2FTbjJlUzRhUUY0Mk0xOEhGZGJ5dklQdkhuR1FUeXk5dDlCYVB1LUtOQ2drWkhINFFrczk"),
    ("33. 宏福苑五級火聽證會｜政府方結案陳詞（庭刊，07月16日）", "https://news.google.com/rss/articles/CBMixwJBVV95cUxPcUdiVzBPVEVnNDZjUkpUaW9TakZ4NXNmRW9IQWJFdFQwVFRZcGJYY3I1OUVZbFFoeUNHbUc4RU1sd0xoWm5yVzRENVM5NXpWNS1jNWx2MHVMUmpmRkM4Zzl3SjloYWZienM5ZDA2NExacjJIazh"),
    ("34. 宏福苑火災聽證會｜物管置邦興業稱在大維修無監督角色（明報新聞網，07月15日）", "https://news.google.com/rss/articles/CBMiswFBVV95cUxPNEtHcXh5UElvZ2VfUUo2VEl2bllXQ1BSUEdON0c2blBCa3hLM29fY1JvZDdYLWNEU08xNFZIWWt4TlpsY0RyVVd4UWIzR25QYlhQcTBPaUhnLUZyMElXQ2dPVFdqZHhQWndMUlVDb0FpdzJ6ZGl"),
    ("35. 宏福苑火災聽證會｜政府代表稱監管責任非火災直接成因（明報新聞網，07月16日）", "https://news.google.com/rss/articles/CBMiswFBVV95cUxPSUhvTnBwbnhwaTZFVF9XamhOMmRGTXduX050QTZrOFViV1B3ZWlfY0J0S0pueGplejFSWm95NVhyVllRRUpnS19rS2pGYmpLbFFvUmY3d2xXOHBMUVZSTE5Ib2N0YjFoRWtUWmk1RlAwZVJvMWI"),
    ("36. 宏福苑火災聽證會｜政府：六大因素促成火災（明報新聞網，07月16日）", "https://news.google.com/rss/articles/CBMiswFBVV95cUxOck51Sm1GSURiclBXeHYyTndac3gxS2RMUzI5T2NabXJaQWx5ZFdEZW9GZm5pZXdZaFhxVU5zY1NOczFVM2V0TlVzTkc3Y25UNzUzWlFCUHI0clYzcXR2cVVNNjFNcHZrM0hwNnNidGhBbjBQcEJ"),
    ("37. 宏福苑火災聽證會｜政府稱識別5個制度弱點（明報新聞網，07月16日）", "https://news.google.com/rss/articles/CBMiswFBVV95cUxOeDYtM3hBVF90SWZUbThMSFdJdjN3eE1YVkZ6Q09kNjRHZTN0aDdxNmlWS0hwSVZ5YVEwQ2tteV9RVk1VemlzZHBEczZyTGZaeHY3TXB4c2lFZ1BTdHVHLVVwYWZoQzdUR0tMcUkyODR5UUZBY2R"),
    ("38. 宏福苑居民：一句「對不起」及認責非奢侈（明報新聞網，07月16日）", "https://news.google.com/rss/articles/CBMiswFBVV95cUxPRVZiSk82SDB4em0xdTR0d1RCS3NqVHV0NzE3TTNXUlFSUGRidTcyWkphV3EyaGI1b3Q2RGlia0VjaWRKeVJsR1RlUEpua1Q1V2tFV0xWN3lSSmJSQ0Z2UDRIeVc2b1lTNndKcUtaN1Z5bDlQM1R"),
    ("39. 宏福苑火災聽證會｜居民代表律師（明報新聞網，07月16日）", "https://news.google.com/rss/articles/CBMiswFBVV95cUxQQjNVU21iVXFOTmp3c3dIVDFyeXJ1UFJVSmQxSkpwNGU0TVphNTkyN2tpejQzcG5MYms4M08wa1Fnb0RwOXhYTGxZai00WGlLemM2OFk2Y2ZTSzRIVVZhSzg2Z1dSdWR3c2dOTDFiYVM1dmVvUG9"),
    ("40. 【持續更新】宏福苑火災聽證會｜政府指六大因素引發火災（明報新聞網，07月16日）", "https://news.google.com/rss/articles/CBMi_wRBVV95cUxQc0dOVjBOdVNDU3o1V3VYbTk3Nzk2MEY3LUJFaFB5OUhZODZQMmFNcXlfczZGalB0QXQtRUdTdDBtcVVNNE91aTVXMFp6NU5MN3pQVVlpaXR3cGtxeDA1SFZPTHJtd1ZZYVJzUUR6VjkxRmVlVUV"),
    ("41. 旁聽居民批淡化責任（明報新聞網，07月16日）", "https://news.google.com/rss/articles/CBMiswFBVV95cUxPb3hpSDNzMnVwczRleHVkODNSOVhDTDBIZDBSLXZUNmwyeFVmMXhRSE4wMHctbGFManBHQ3BTNzNkVXFldlhPT2hEa3lEcEdEeWNXOS1rdXdyWncwUERVY2lwa0xiWEw0am9SY28zcHktMnNvb0s"),
    ("42. 鄧國權黃碧嬌無作供 居民陳辭點名（明報新聞網，07月16日）", "https://news.google.com/rss/articles/CBMixAJBVV95cUxPTWk1ZXBlUEI5NzhZVkpmNElsRE43R0xid1ViRmgyUUxHenN3VDVORDNyYmMyc2llU2hZSVF5enRQLUFaWDJ1c2xGcS1DbjBEVTlpUy1uYW5pYTQ1ZlF6UHBERjMtRUoxNzdIekRnUVVueGJVOTR"),
    ("43. 宏福苑火災聽證會｜有居民認為政府部門對火災有責任（明報新聞網，07月16日）", "https://news.google.com/rss/articles/CBMiswFBVV95cUxQSXZsem11Vm5xRGU3NDFuYm5Ra0NBUndXNnJSOXNhNzRCOTBOMXFqV2dBSXZFby1yeFFGZ0hmczRLZjRKZnRWUXpsbzBCN2pXal9CaEREbEhIVkg2d0ZxbTBncl9HSElPUFRSNjVpUHNMS1FOSmR"),
    ("44. 宏福苑火災聽證會｜政府：火警規模前所未見（明報新聞網，07月16日）", "https://news.google.com/rss/articles/CBMiswFBVV95cUxOcldOS2w2azVtWDgxRWQxcTh2TzE5dE9LaWdFUTJ3MVItdkxwOXo1YXoxdmozQXBjNGs1bkNVWnQzLVUzakRsNGNTbFJNZGFTck5OelI2SVRrZy1xWGRqeGdEYlBJVDVHaXlLd3V6UWFhdjEzcnV"),
    ("45. 識別5「系統性弱點」（明報新聞網，07月16日）", "https://news.google.com/rss/articles/CBMixgJBVV95cUxORUZ6RDNqLVhCVGc5Y3Itb2otcXotX2NXeUk4QWFLeDlSVnk3ekhXNUxGaXFmVVdFcDRFWVp1MGJWOUE0Z3BjN3RJcUVZaTBpN1drWmRabzB0MlYxZXMzRHhNYnFhNVR3ampGd1FNanZ2WnQxSDQ"),
    ("46. 居民總結：環環失誤釀禍（明報新聞網，07月16日）", "https://news.google.com/rss/articles/CBMinwFBVV95cUxQZnp4QXZvdllMZklJWkRhaW4waTN4R3NiV2t5QVItWndVNm9mQlRseEZfMWlncVdLYnhvTHB5amdHeHkxdUtiMzJrX2JPblFPWm5NRUtGZ1BSYUthbjdtSHJUOFkxOEtldWtkMExTenZPa1NQWV9"),
    ("47. 宏福苑聽證會第六輪周三起舉行3場（星島頭條，07月13日）", "https://news.google.com/rss/articles/CBMizgNBVV95cUxOU1VLaWZINHpEa09nYWtneGJ1LUhhRkctdm1sQ1REaXFhbmQzVTVwWHNzaW1VOHJ2ZnU3clNjYWtMbHZWSlcxQnZneGJrYmhkeF9ySVo1YnhoMF9rSHItNnlySXRfazBaclNSZXJhSlZEaVF1R2Q"),
    ("48. 宏福苑聽證會｜政府承認監管制度存五大弱點（星島頭條，07月16日）", "https://news.google.com/rss/articles/CBMi7wNBVV95cUxPSl9vM0RrUEdoa2FhRUtrVW0tcEtyUk9wbHQ0dExMb24xUmRnaGtLVDJWOFQyUE83bGI3SUIyTXI2YzBDYkNfRUNrdE94aUNWMHdkVEE0R3hfWlRrZHh0bF92TG9QLU1PNjBOaVJVN0FuZ3lyQ3N"),
    ("49. 宏福苑聽證會｜何偉豪留在宏泰閣嘗試協助疏散（星島頭條，07月16日）", "https://news.google.com/rss/articles/CBMi7ANBVV95cUxPV0p3b0d6VFlLRjJ5N1JrV3I0Q3p6cVJlWnBKbXN2RVh4d1J5OHplYmp1MGl2dF9hRERfcDlBRlJ5QndfdlVKN1RNN19HYWd2OHVyR2FiMjVfMnFKd0ZfcFBiYlpZcXdKRGdF"),
    ("50. 宏福苑大火最終一輪聽證會（星島頭條，07月17日）", "https://news.google.com/rss/articles/CBMitgNBVV95cUxQMkVvNEVXN2xYMVF4c0ZxNWNUS3hQdUdaTnN0a3RLdXNlVnpBTmR2VTV3LW9uQjE3Z2hVOTRlZjgtUTd6LW9oMGJlMUt5d3BjNmp3X0dBRnJNb0ZPcG9KWGpYOW9iS19nZ2tuQ0d6b2RjY0RzVg"),
]

os.makedirs('/tmp/scrapling_output', exist_ok=True)

results = []
for i, (label, gn_url) in enumerate(GN_LINKS, 1):
    out_file = f'/tmp/scrapling_output/gn_{i:02d}.html'
    print(f"\n[{i}/50] 正在抓取: {label[:40]}...", flush=True)
    print(f"    URL: {gn_url[:80]}", flush=True)
    
    try:
        result = subprocess.run(
            ['/usr/local/bin/scrapling', 'extract', 'stealthy-fetch', '--no-headless',
             gn_url, out_file],
            capture_output=True, text=True, timeout=60
        )
        
        real_url = 'PENDING'
        source = 'N/A'
        article_id = 'N/A'
        
        if os.path.exists(out_file):
            with open(out_file, 'r', encoding='utf-8', errors='ignore') as f:
                html = f.read()
            
            # Extract og:url
            og_match = re.search(r'og:url["\s]+?:?\s*["\']([^"\']+)["\']', html)
            if og_match:
                real_url = og_match.group(1)
            
            # Extract canonical
            if real_url == 'PENDING':
                can_match = re.search(r'<link[^>]+rel=["\']canonical["\'][^>]+href=["\']([^"\']+)["\']', html, re.I)
                if can_match:
                    real_url = can_match.group(1)
            
            # Extract article:published_time
            time_match = re.search(r'article:published_time["\s]+?:?\s*["\']([^"\']+)["\']', html)
            if time_match:
                article_id = time_match.group(1)
            
            # Extract source/publisher
            pub_match = re.search(r'publisher["\s]+?:?\s*["\']([^"\']+)["\']', html)
            if pub_match:
                source = pub_match.group(1)
            
            # Extract from JSON-LD
            json_match = re.search(r'"url"\s*:\s*"([^"]+)"', html)
            if real_url == 'PENDING' and json_match:
                real_url = json_match.group(1)
            
            # Extract from <a> redirect in Google page
            redirect_match = re.search(r'href="(https?://(?!news\.google\.com)[^"]+)"[^>]*>\s*Visit', html, re.I)
            if redirect_match:
                real_url = redirect_match.group(1)
        
        if real_url == 'PENDING':
            real_url = f'解析失败 (文件存在: {os.path.exists(out_file)})'
        
        print(f"    ✅ 真实URL: {real_url[:100]}", flush=True)
        print(f"    📰 来源: {source}", flush=True)
        
        results.append({
            'num': i,
            'label': label,
            'gn_url': gn_url,
            'real_url': real_url,
            'source': source,
            'article_time': article_id,
        })
        
    except subprocess.TimeoutExpired:
        real_url = '⏱️ 超时'
        print(f"    ❌ 超时", flush=True)
        results.append({'num': i, 'label': label, 'gn_url': gn_url, 'real_url': 'TIMEOUT', 'source': 'N/A', 'article_time': 'N/A'})
    except Exception as e:
        real_url = f'❌ 错误: {e}'
        print(f"    ❌ 错误: {e}", flush=True)
        results.append({'num': i, 'label': label, 'gn_url': gn_url, 'real_url': f'ERROR: {e}', 'source': 'N/A', 'article_time': 'N/A'})
    
    time.sleep(2)  # polite delay

# Save results
import json
with open('/tmp/scrapling_output/resolved_links.json', 'w', encoding='utf-8') as f:
    json.dump(results, f, ensure_ascii=False, indent=2)

print("\n\n=== 最终结果汇总 ===")
for r in results:
    print(f"{r['num']:2d}. [{r['source']}] {r['real_url'][:80]}")
print(f"\n已保存到 /tmp/scrapling_output/resolved_links.json")
