Explorer
/proc/1357821/root/tmp/p7_discovery.py
← Zurück ↓ Download
import asyncio, json, re, time, urllib.parse, urllib.request, xml.etree.ElementTree as ET
from datetime import datetime, timezone
from playwright.async_api import async_playwright

ENTITIES={
'Murprotec':'murprotec_baleares','HUMICONTROL':'humicontrol_mallorca','Humexpert':'humexpert_mallorca','ISOTEC':'isotec_mallorca','Conforthome':'conforthome_mallorca','First Mallorca':'first_mallorca','Porta Mallorquina':'porta_mallorquina','Engel & Völkers Mallorca':'engel_voelkers_mallorca','Property Care Mallorca':'property_care_mallorca'}
PLATS={'facebook':('facebook.com',re.compile(r'facebook\.com/.+/(?:posts|videos|reel|permalink\.php)',re.I)),'linkedin':('linkedin.com',re.compile(r'linkedin\.com/(?:posts|feed/update)',re.I)),'instagram':('instagram.com',re.compile(r'instagram\.com/(?:p|reel)/',re.I))}

def bing(entity, platform):
 q=f'site:{PLATS[platform][0]} "{entity}"'
 try:
  u='https://www.bing.com/search?q='+urllib.parse.quote(q)+'&format=rss&count=25'
  raw=urllib.request.urlopen(u,timeout=20).read(); root=ET.fromstring(raw); out=[]
  for i in root.findall('.//item'):
   url=(i.findtext('link','') or '').strip(); title=(i.findtext('title','') or '').strip(); desc=(i.findtext('description','') or '').strip(); pub=(i.findtext('pubDate','') or '').strip()
   if PLATS[platform][0] in url: out.append({'url':url,'title':title,'snippet':desc,'date_raw':pub,'is_post':bool(PLATS[platform][1].search(url))})
  return {'query':q,'results':out}
 except Exception as e:return {'query':q,'error':str(e),'results':[]}

async def main():
 rows=[]
 async with async_playwright() as pw:
  browser=await pw.chromium.launch(headless=True,executable_path='/snap/bin/chromium',args=['--no-sandbox'])
  page=await browser.new_page()
  for entity,eid in ENTITIES.items():
   for platform in PLATS:
    q=urllib.parse.quote('"'+entity+'"')
    url='https://www.social-searcher.com/google-social-search/?q='+q
    rec={'entity':entity,'watch_entity_id':eid,'platform':platform,'url':url,'retrieved_at':datetime.now(timezone.utc).isoformat(),'http':None,'results':[],'repeat':None}
    try:
     r=await page.goto(url,wait_until='domcontentloaded',timeout=30000); rec['http']=r.status
     await page.wait_for_timeout(1800)
     frame=page.frame(name=None)
     # select the platform iframe by URL, then inspect its rendered Google CSE DOM
     fs=[f for f in page.frames if f.url and platform+'cse.html' in f.url]
     if fs:
      f=fs[0]
      links=await f.locator('a').evaluate_all('(els)=>els.map(a=>({url:a.href,text:(a.innerText||a.textContent||"").trim()})).filter(x=>x.url)')
      body=(await f.locator('body').inner_text())[:8000]
      for x in links:
       if PLATS[platform][0] in x['url']:
        rec['results'].append({'url':x['url'],'text':x['text'],'is_post':bool(PLATS[platform][1].search(x['url']))})
      rec['body_excerpt']=body
    # repeat same query once, measuring stable URL intersection
     await page.reload(wait_until='domcontentloaded',timeout=30000); await page.wait_for_timeout(1800)
     fs2=[f for f in page.frames if f.url and platform+'cse.html' in f.url]
     urls2=set()
     if fs2:
      links2=await fs2[0].locator('a').evaluate_all('(els)=>els.map(a=>a.href).filter(Boolean)')
      urls2={u for u in links2 if PLATS[platform][0] in u and PLATS[platform][1].search(u)}
     urls1={x['url'] for x in rec['results'] if x['is_post']}
     rec['repeat']={'second_post_count':len(urls2),'intersection':len(urls1 & urls2),'stable':bool(urls1 and urls1==urls2)}
    except Exception as e: rec['error']=str(e)
    rows.append(rec); print(entity,platform,rec['http'],len(rec['results']),rec.get('repeat'))
  await browser.close()
 # Bing comparison, bounded and no credentials/cookies
 for entity,eid in ENTITIES.items():
  for platform in PLATS:
   rows.append({'entity':entity,'watch_entity_id':eid,'platform':platform,'source':'bing_rss','retrieved_at':datetime.now(timezone.utc).isoformat(),'bing':bing(entity,platform)})
   time.sleep(.25)
 json.dump(rows,open('/tmp/p7_discovery.json','w'),ensure_ascii=False,indent=2)
 print('WROTE',len(rows))
asyncio.run(main())