"""Internet aramasi ve sayfa okuma: Codex'e sonradan eklenen modeller icin (11 Ekim 2026). Codex'in yerlesik web aramasi OpenAI sunucusunda calisir ve yalniz Codex'in kendi modellerine verilir; kopru onu ek modele giden arac listesinden atar. Ek model aramayi bu betigi kabuk araciyla calistirarak yapar (internet.py modele komutu soyler). Anahtar gerekmez; yalniz standart kitaplik. python ara.py ara "sorgu" [--adet 8] python ara.py oku [--en-cok 8000] """ import argparse import html import re import sys import urllib.parse import urllib.request import xml.etree.ElementTree as ET UA = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/126.0 Safari/537.36" ARAMA = "https://html.duckduckgo.com/html/?" SURE = 25 EN_COK_BAYT = 3_000_000 def indir(adres, sure=SURE): adres = urllib.parse.quote(adres, safe=":/?#[]@!$&'()*+,;=%~") # Turkce harfli adres ("/wiki/Türkiye") istek = urllib.request.Request(adres, headers={"User-Agent": UA, "Accept-Language": "tr,en;q=0.8"}) with urllib.request.urlopen(istek, timeout=sure) as yanit: ham = yanit.read(EN_COK_BAYT) kodlama = yanit.headers.get_content_charset() or "utf-8" tur = yanit.headers.get_content_type() try: return ham.decode(kodlama, "replace"), tur except LookupError: return ham.decode("utf-8", "replace"), tur def _duz(parca): return re.sub(r"\s+", " ", html.unescape(re.sub(r"<[^>]+>", "", parca))).strip() def sonuclari_coz(sayfa, adet=8): """Arama sayfasindan [(baslik, adres, ozet)].""" cikti = [] for blok in re.split(r']+class="[^"]*\bresult\b[^"]*"', sayfa)[1:]: bag = re.search(r']+class="result__a"[^>]+href="([^"]+)"[^>]*>(.*?)', blok, re.S) if not bag: continue adres = html.unescape(bag.group(1)) ic = re.search(r"[?&]uddg=([^&]+)", adres) if ic: adres = urllib.parse.unquote(ic.group(1)) if adres.startswith("//"): adres = "https:" + adres if "duckduckgo.com/y.js" in adres: # reklam continue ozet = re.search(r'class="result__snippet"[^>]*>(.*?)', blok, re.S) cikti.append((_duz(bag.group(2)), adres, _duz(ozet.group(1)) if ozet else "")) if len(cikti) >= adet: break return cikti def metne_cevir(sayfa): """HTML -> okunur duz metin (betik, bicim ve gezinme kisimlari atilir).""" sayfa = re.sub(r"(?is)<(script|style|noscript|svg|nav|footer|header|form|iframe)\b.*?", " ", sayfa) sayfa = re.sub(r"(?is)", " ", sayfa) sayfa = re.sub(r"(?i)<(br|/p|/div|/li|/h[1-6]|/tr)\b[^>]*>", "\n", sayfa) metin = html.unescape(re.sub(r"<[^>]+>", " ", sayfa)) satirlar = [re.sub(r"[ \t\r\f\v]+", " ", s).strip() for s in metin.split("\n")] return "\n".join(s for s in satirlar if s) def ara(sorgu, adet=8, indirici=indir): sayfa, _ = indirici(ARAMA + urllib.parse.urlencode({"q": sorgu})) sonuc = sonuclari_coz(sayfa, adet) if not sonuc: if 'no-results' in sayfa.lower() or 'no results found' in sayfa.lower(): return "Sonuç bulunamadı. En fazla bir farklı sorgu deneyebilirsin." # DDG bot kontrolünü/bozuk HTML'yi sonuç yok diye göstermeyiz. Tek yedek istek. try: rss, _ = indirici('https://www.bing.com/search?' + urllib.parse.urlencode({'format': 'rss', 'q': sorgu})) kok = ET.fromstring(rss) if kok.tag != 'rss' or kok.find('channel') is None: raise ValueError('RSS arama yanıtı değil') sonuc = [(i.findtext('title') or '', i.findtext('link') or '', _duz(i.findtext('description') or '')) for i in kok.findall('./channel/item') if (i.findtext('link') or '').startswith(('https://', 'http://'))][:adet] except (ValueError, ET.ParseError, OSError) as hata: raise RuntimeError('Arama hizmeti engellendi veya yanıtı okunamadı; sorguları değiştirerek tekrar etme.') from hata if not sonuc: return "Sonuç bulunamadı. En fazla bir farklı sorgu deneyebilirsin." return "\n\n".join(f"{i}. {b}\n {a}\n {o}" for i, (b, a, o) in enumerate(sonuc, 1)) def oku(adres, en_cok=8000, indirici=indir): if not re.match(r"https?://", adres): adres = "https://" + adres sayfa, tur = indirici(adres) metin = metne_cevir(sayfa) if "html" in tur or " en_cok: metin = metin[:en_cok] + f"\n[... kesildi: {len(metin)} karakterin ilk {en_cok} karakteri]" return metin or "Sayfada okunur metin bulunamadı." def main(argv=None): p = argparse.ArgumentParser(description="Internet aramasi ve sayfa okuma") alt = p.add_subparsers(dest="is_", required=True) a = alt.add_parser("ara"); a.add_argument("sorgu", nargs="+"); a.add_argument("--adet", type=int, default=8) o = alt.add_parser("oku"); o.add_argument("adres"); o.add_argument("--en-cok", type=int, default=8000) s = p.parse_args(argv) try: metin = ara(" ".join(s.sorgu), max(1, min(s.adet, 20))) if s.is_ == "ara" else oku(s.adres, max(500, s.en_cok)) kod = 0 except Exception as e: metin, kod = f"Hata: {type(e).__name__}: {e}", 1 sys.stdout.buffer.write((metin + "\n").encode("utf-8", "replace")) return kod if __name__ == "__main__": sys.exit(main())