Her “en hızlı Python HTML parser” yazısı sonunda selectolax adını geçirir ve hepsi hikâyeyi “BeautifulSoup’tan çok daha hızlı” diye kapatır. Bu kısmı doğru. Ama çoğu yazıda atlanan yer şu: selectolax’ı lxml ile yan yana koyduğunuzda ne oluyor? Çünkü orada “en hızlı” ifadesinin sonuna bir yıldız eklemek gerekiyor.
Bu yüzden işi düzgünce ölçtüm: selectolax’ı (iki backend’iyle birlikte), lxml’yi, html.parser ve lxml üzerinde çalışan BeautifulSoup’u ve parsel’i; 1 KB’den 10 MB’ye kadar beş farklı sayfa boyutunda, her ölçümü üç ayrı process çalıştırmasının medyanı olarak karşılaştırdım. Sonuç: selectolax, BeautifulSoup’u açık ara geçti ve ham lxml ile berabere kaldı — ardından saf ayrıştırma adımında lxml’ye yenildi. Aşağıdaki tüm rakamlar tek bir makineden alınmış geçici sonuçlardır (macOS arm64, Python 3.14.2); script’ler repoya eklendi, bu yüzden beni alıntılamadan önce kendi makinenizde çalıştırın.
selectolax tam olarak nedir, ne değildir?
selectolax, HTML5’i ayrıştıran ve CSS seçicilerle sorgulayan iki C motoruna — Modest ve Lexbor’a — bağlanan bir Python kütüphanesidir. Bir tarayıcı değildir, bir crawler değildir, butona basınca veri çeken anlamında bir “scraper” da değildir. Sizden HTML bloğunu alıp, sayfayı zaten indirdikten sonra ona uyguladığınız parçadır. Geliştiricinin kendi tek cümlelik tanımı da şu: “Cython ile yazılmış, Modest ve Lexbor motorlarını kullanan, CSS seçicili hızlı bir HTML5 ayrıştırıcı.”
İki backend vardır ve aralarındaki fark, dokümanların anlattığından daha önemlidir:
LexborHTMLParser(Lexbor motoru) — README’nin 2024 itibarıyla kullanmanızı önerdiği seçenek.HTMLParser(Modest motoru) — ilk sürüm; aynı README’ye göre altındaki C kütüphanesi “artık bakım görmüyor.”
Hız konusuna geçmeden önce birkaç önemli not: repo anlık görüntüsüne göre 2026-07-10 itibarıyla selectolax 1.653 yıldıza sahip ve en güncel sürüm v0.4.10 (Mayıs 2026). PyPI ise Python sürümünü >=3.9,<3.15 olarak sabitliyor. Kurulum, bu incelemenin en az dramatik kısmı: pip install selectolax bana 2.3 MB’lık önceden derlenmiş cp314 wheel dosyasını indirdi ve Python 3.14 üzerinde hemen çalıştı — tarayıcı indirme yok, doctor adımı yok, derleme yok. Tarayıcı tabanlı araçlara göre sessiz ama büyük bir avantaj bu. Sadece import olur ve çalışır.
Bir lisans detayı da şimdiden söylenmeli: Python bağlayıcısı MIT lisanslıdır, ancak wheel’in içine gömülü motorlar kendi lisanslarına sahiptir — Modest LGPL-2.1, Lexbor ise Apache-2.0. Yani “selectolax MIT lisanslıdır” ifadesi Python kodu için doğru, ama dağıttığınız gerçek binary için eksik kalır. Hukuk ekibiniz yeniden dağıtılan bileşenleri önemsiyorsa, işaret edilmesi gereken fark budur.
Hız sorusunun gerçek sayılarla cevabı
Ölçtüğüm görev şuydu: HTML string’ini ayrıştır, her <h3 class="title"> metnini çek, her <a> bağlantısının href değerini al. Medyan gecikme milisaniye cinsinden ölçüldü; üç ayrı process çalıştırmasının medyanı alındı. C tabanlı ayrıştırıcılarda run’lar arası fark çoğu boyutta yaklaşık %5’in altında kaldı. Herhangi bir hücre zamanlanmadan önce, parser’ların çıktısı bir içerik hash’ine indirgeniyordu; böylece sessizce daha az iş yapan bir parser yakalanıp elenebilsin. Bu sayfalarda altı sonuç da her boyutta eşleşti, yani bu gerçek bir elma-elma karşılaştırması. Tam veri bench_parse.json dosyasında duruyor.

| Sayfa | selectolax (Lexbor) | selectolax (Modest) | lxml | parsel | BS (lxml) | BS (html.parser) |
|---|---|---|---|---|---|---|
| 1 KB | 0.027 | 0.029 | 0.036 | 0.044 | 0.281 | 0.323 |
| 10 KB | 0.160 | 0.171 | 0.166 | 0.228 | 1.705 | 2.049 |
| 100 KB | 1.464 | 1.565 | 1.423 | 2.020 | 16.5 | 20.6 |
| 1 MB | 14.901 | 16.9 | 14.177 | 20.9 | 181.9 | 232.6 |
| 10 MB | 159.9 | 247.9 | 172.9 | 231.9 | 2261.6 | 2788.7 |
BeautifulSoup’a karşı: yaklaşık 12-17x ve popüler anlatı gerçeği küçümsüyor
Bu oranları çevirdiğimizde selectolax-Lexbor, 1 KB’lık sayfada BeautifulSoup(html.parser)’dan yaklaşık 12x, 10 MB’da ise yaklaşık 17x daha hızlı çıkıyor; aynı aralıkta BeautifulSoup(lxml)’dan da yaklaşık 10-14x daha hızlı. İnternette dolaşan “selectolax, BeautifulSoup’tan 4-5x hızlı” ifadesi html.parser karşısında fazla düşük, lxml tabanlı BeautifulSoup’a karşı ise ancak kabaca doğru. Gerçek çarpan, hangi BeautifulSoup varyantından bahsettiğinize ve sayfa başına ne kadar veri çıkardığınıza bağlı.
Bu sonuç, README’deki kendi benchmark’ıyla da uyumlu; orada BeautifulSoup(html.parser) üzerinde 25.5x avantaj ima ediliyor. İki sayı da yanlış değil. README’nin görevi (küçük ana sayfalardan başlık, bağlantı, script ve meta çekmek) daha az veri ayıklıyor; bu da BeautifulSoup’un her parse başına getirdiği ek yükü daha belirgin hale getiriyor. Daha dar bir aralıkta özetlersek: gerçek dünya parse+extract işlerinde selectolax, BeautifulSoup’tan kabaca 10-15x hızlı; küçük sayfalarda ve hafif çıkarımda fark daha da büyüyor.
Eğer mevcut darboğazınız BeautifulSoup ile sayfa işleyen bir kod yığınıysa, bu geçiş kendini amorti eder. Bu tartışmalı bir nokta değil. Bir sonraki kısım ise daha tartışmalı.
lxml’ye karşı: başabaş — ve herkesin gözden kaçırdığı bölümde lxml önde
100 KB ve 1 MB satırlarına tekrar bakın. Lexbor ile lxml birbirine yaklaşık %5 içinde, aralıkları çakışıyor ve benim metodolojime göre bu berabere demek — kazanan yok, “daha hızlı” yok. selectolax’ın gerçekten öne çıktığı tek yer 10 MB’lık sayfa (159.9 ms’ye karşı 172.9 ms, yani örtüşmeyen aralıklarla %8.1 fark). Yani tam görevde selectolax, lxml ile aynı seviyede; yalnızca en büyük belgelerde onu geçiyor.

Sonra ağaç oluşturmayı CSS sorgulamadan ayırdım ve sonuç, çoğu yazının kaçırdığı şekilde tersine döndü. Saf ayrıştırmada, hiç sorgu olmadan, bu makinede lxml selectolax-Lexbor’dan sürekli olarak yaklaşık %33-34 daha hızlıydı — 10 MB sayfada 77.9 ms’ye karşı 116.6 ms. Tam görevde ise ikisi zaten birbirine yaklaşıyor; benim çalışma varsayımım da şu (bu, bir atıf deneyiyle kanıtladığım bir şey değil): bu sayfalarda CSS sorgusu toplam sürenin küçük bir parçası olduğu için lxml’nin parse aşamasındaki avantajı toplamda silikleşiyor ve sonuçlar birbirine geliyor.
Bu incelemedeki en çok eleştirilebilecek iddia bu, o yüzden nedenini açık söylemek istiyorum. Çünkü yaygın kanaatin tersine gidiyor ve saf parse’ı izole eden bulduğum tek yayımlanmış benchmark — aows.jpt.sh — bunun tersini, yani selectolax’ın yaklaşık 4x hızlı olduğunu söylüyor. Bu yüzden sonucu sınırlandırdım: tek platformlu (macOS arm64, Python 3.14, önceden derlenmiş cp314 wheel’leri — Linux x86_64 veya source build test edilmedi), dört sayfa boyutunda çapraz doğrulandı ve hepsinde aynı kaldı; ayrıca API kaynaklı bir yan etkiyi dışlamak için iki farklı lxml API’siyle yeniden doğrulandı. Her iki lxml API’si de her boyutta selectolax-Lexbor’u geçti. Ben burada “lxml daha hızlı ayrıştırır” sonucunu kesin hüküm olarak sunmuyorum — bunu, elimdeki script ile birlikte, yayımlanmış sayıların çoğuna karşı benim benchmark’ımın verdiği sonuç olarak sunuyorum. Sizin sistemde çalıştırın.
Bir katman daha: 100.000 <a> öğesini düz bir sayfada sorguladığımda lxml ile selectolax-Modest berabere kaldı (33.30 ms’ye karşı 34.19 ms, aralıklar çakışıyor); selectolax-Lexbor ise ikisinin de yaklaşık %15 gerisinde kaldı. Üç C motorunun ortak noktası, toplu seçimde parsel ve BeautifulSoup’tan 5-7x hızlı olmaları; esas yavaşlık, düğüm başına Python nesnesi modelinden geliyor. Dolayısıyla “selectolax toplu CSS seçiminde en hızlısıdır” da doğru değil — Modest sadece lxml ile başa baş gidiyor, Lexbor ise ona yeniliyor.
Benim gerçekten sahip çıkabileceğim sonuç şu: selectolax’ın lxml’ye üstünlüğü geniş kapsamlı, tam görev hızında değil. Sadece en büyük sayfada kazanıyor. Gücü başka yerlerde yatıyor — API ergonomisi, bozuk girdiye davranışı ve modern CSS desteği; incelemenin geri kalanı da bunları ele alıyor.
Bellek kullanımı ve soğuk başlangıç: profiler’a değil RSS’ye bakarak sıralayın
Bellek kısmında kendi eski rakamımı düzeltmem gerekiyor ve bu düzeltme aslında işin özü. 10 MB sayfada, tracemalloc kapalıyken RSS farkı olarak ölçtüğümde, BeautifulSoup selectolax veya lxml’ye kıyasla yaklaşık 1.5-1.8x daha fazla bellek kullanıyor — oran 1.51x’den (BS-lxml, 218.4 MB; Lexbor 144.6 MB) en üst noktada 1.75x’ye kadar çıkıyor. selectolax ve lxml daha hafif sınıfta yer alıyor; RSS bazında en hafif olan lxml.

Daha önceki bir çalışmamda “~3x” demiştim; bu sayı öğretici bir nedenle yanlıştı: tracemalloc açıkken ölçülmüştü ve tracemalloc’un her allocation için tuttuğu kayıtlar, en çok allocation yapan parser’ın görünen RSS değerini yaklaşık iki katına çıkarıyor. Parser belleğini ölçenler için not: profiler kapalıyken RSS’ye göre sıralayın. Tracemalloc zirvesine göre sıralama, özellikle C tabanlı parser’ları yanlış yerleştiriyor — selectolax-Lexbor’u Modest’ten daha ağır gösterdi; oysa gerçek RSS’de birbirlerine yakınlar. Burada gerçekten en ağır olan BeautifulSoup; sadece kirlenmiş bir ölçüm aracının gösterdiği gibi 3x farkla ağır değil.
Soğuk başlangıç küçük ama gerçek: selectolax yaklaşık 14 ms’de import oluyor; bu lxml ile kabaca aynı ve bs4 ya da parsel’den yaklaşık 2.3x daha hızlı. Bir CLI aracı veya her çağrıda import süresinin hissedildiği serverless bir fonksiyon yayınlıyorsanız, bu fark önemlidir.
CSS seçici kapsamı: güçlü, ama birkaç gerçek açık var
CSS kapsamı için 41 maddelik bir matris kullandım; her seçici, doğru cevap kümesi bilinen bir fixture üzerinde test edildi. Buna bir de Lexbor motorunu bozmak için hazırlanmış kasıtlı hata avı eklendi. Her vaka ayrı bir subprocess’te çalıştırıldı; bu gerekli çıktı çünkü bunlardan biri tüm interpreter’ı çökertiyor. Sonuçlar:

| Motor | GEÇTİ | YANLIŞ | DESTEKLENMİYOR | PROCESS_ABORT |
|---|---|---|---|---|
| soupsieve | 41 | 0 | 0 | 0 |
| selectolax Lexbor | 39 | 0 | 2 | 0 |
| lxml (cssselect) | 37 | 1 | 3 | 0 |
| parsel (cssselect) | 37 | 1 | 3 | 0 |
| selectolax Modest | 35 | 3 | 2 | 1 |
Kasıtlı zorlayıcı seçiciler devreye girince Lexbor açık ara kazanan olmuyor — 41/41 ile temiz çıkan soupsieve, Lexbor’un 39/41 sonucunun önünde. Lexbor’un kaçırdığı iki durum :lang(en) ve :dir(rtl); bunları parse hatasıyla reddediyor. Bunun dışında :has(), :is(), :where() ve büyük/küçük harf duyarsız attribute’larda kusursuz.
Ama Lexbor’un gerçekten parladığı yer cssselect yığınına karşı. README’de yıldız seçici olarak gösterilen div > :nth-child(2n+1):not(:has(a)), hem selectolax motorlarında hem soupsieve’de doğru kümeyi döndürüyor; ancak lxml ve parsel’de hata vermeden yanlış kümeyi veriyor. Scrapy veya parsel’e bu seçiciyi kopyalayan bir scraper, sessizce hatalı sonuç alır. Çerçeveyi net söyleyeyim: cssselect, :has() desteğini 1.2.0 sürümünden beri (2022) parse ediyor ve ben 1.4.0’ı test ettim; yani mesele “desteklenmiyor” değil, “destekleniyor ama bileşik yapıyı yanlış değerlendiriyor.” Bu belirli bileşikte sessiz yanlış sonuç davranışı cssselect takip kaydında ayrı bir başlık olarak yok; orada :has() sınırlamaları hata fırlatma olarak kaydedilmiş. Lexbor ayrıca cssselect’in tamamen reddettiği büyük/küçük harf duyarsız attribute bayrağını [data-role="LEAD" i] düzgün işliyor.
Yine de göç kararını asıl belirleyecek iki boşluk var. selectolax hiç XPath desteklemiyor — iki backend de xpath() sunmuyor — ve ::text / ::attr() gibi sözde elementler de yok; çünkü bunlar gerçek CSS değil, parsel/Scrapy uzantısı. Mevcut scraper’larınız XPath’e dayanıyorsa, karşılaşacağınız en büyük duvar budur; kütüphane değiştirmekten çok seçicileri yeniden yazmanız gerekir. Öte yandan Lexbor, ne lxml’nin, ne parsel’in, ne de standart CSS’nin sunduğu, metin eşleştirmede büyük/küçük harf duyarsız :lexbor-contains("text" i) pseudo-class’ını getiriyor ve dokümantasyondaki gibi çalışıyor.
Çirkin HTML karşısında sağlamlık: selectolax’ın esas hakkı burada
Gerçek scraping, parser’a çöp veri vermek ve onun devrilmemesini ummaktır. 18 saldırgan girdi test ettim ve selectolax’ın lxml’ye karşı en güçlü olduğu kategori burası.
lxml.html.fromstring’e boş bir string veya sadece boşluk verin, ParserError("Document is empty") fırlatır. Her iki selectolax motoru da bunun yerine geçerli, boş bir ağaç döndürür. Bazı URL’lerden boş yanıt dönen bir liste üzerinde çalışan bir scraper için bu, etrafını sarmak zorunda olduğunuz bir try/except daha az demektir. selectolax ayrıca 100.000 öğeyi stack overflow olmadan işledi.
En keskin ayrışma derin iç içe geçmede ortaya çıktı. 1.000 ve 5.000 seviyeli iç içe <div> yapılarında, lxml en derin içeriği sessizce düşürürken selectolax onu koruyor. libxml2, ayrıştırma derinliğini yaklaşık 256 seviyede sınırlar ve ağaçta hata vermeden kırpma yapar; bu yüzden en derin metin erişilemez olur. Her iki selectolax motoru da tam ağacı döndürür. Bu, birazdan anlatacağım <template> tuzağının ters yüzü gibidir: orada Lexbor diğerlerinin tuttuğu içeriği düşürüyor; burada ise lxml, selectolax’ın koruduğu içeriği düşürüyor.
Her hücre zafer değildi. Modest backend, :dir() ile karşılaştığında tüm Python interpreter’ını SIGABRT ile sonlandırıyor — yakalayabileceğiniz bir exception değil, doğrudan prosesin öldürülmesi. Legacy backend’de kalanlar için bu ciddi bir sağlamlık uyarısı; prod ortamında sabaha karşı bir işi çökerten türden bir problem ve bunu ancak yaşayınca fark edersiniz.
Canlıya çıkmadan önce bilmeniz gereken iki sessiz veri kaybı tuzağı
Bunların ikisi de yeni keşif değil — ikisi de upstream’de belgelenmiş durumda — ama ikisi de gerçek veri kaybına yol açıyor, sessizce, ve README’de yeterince vurgulanmıyor.
Lexbor, <template> içindeki <a> öğelerini atlıyor
Test ettiğim canlı MDN sayfasında, selectolax-Lexbor 497 bağlantı bulurken lxml, iki BeautifulSoup backend’i ve hatta selectolax’ın kendi Modest backend’i 508 bağlantı buldu. Eksik olan on bir öğe, <template> içinde duran bir dil değiştirici ve bir tartışma bağlantısıydı (sayfa Lit web bileşenleri kullanıyor).

Kök neden meşrudur: HTML5 spesine göre <template> içeriği normal DOM’a değil, ayrı ve etkisiz bir parçaya ayrıştırılır; Lexbor da buna sıkı sıkıya uyar — tree.css("a") template içeriğine girmez. lxml, iki BeautifulSoup backend’i ve Modest ise template içeriğini ana ağaca düzleştirir; bu yüzden o bağlantıları bulurlar. Bu durum belgelenmiş bir açık issue’dur (selectolax#146, motor kökeni için lexbor#170); iki yorum da savunulabilir — spec’e daha uygun olan Lexbor bile diyebiliriz. Ama önerilen backend’i kullanan geliştirici, hiçbir hata almadan bu veriyi sessizce kaçırır. Ters açıdan bakarsak, diğer parser’lar tarayıcının asla render etmediği etkisiz template içeriğini ortaya çıkarır; bu da kullanıcıların göremeyeceği sahte veri sunabilir. Bu sayfa özelinde güvenli kaçış yolu, Modest backend’i ya da başka bir kütüphanedir.
UTF-8 olmayan bytes, .text() içinde sessizce bozuluyor
selectolax’a geçerli UTF-8 olmayan bytes verirseniz ayrıştırma başarılı olur — bozulma sonra ortaya çıkar ve temiz bir çöküşten daha kötüdür. "<p>café éè</p>".encode("latin-1") verildiğinde, Lexbor’un .text() metodu replacement karakterler döndürür, Modest’in .text() metodu ise sorunlu baytları sessizce atar; .html özelliğine dokunana kadar her iki motor da ancak UnicodeDecodeError fırlatır. Binding, decode işlemini parse anında değil, geri okuma sırasında sıkı UTF-8 olarak yapar. Bu konu, encode/decode sıkılığıyla ilgili bilinen bir selectolax sorunuyla ilişkilidir.
Çözüm tek satırdır ve alışkanlık haline gelmelidir: baytları önce siz decode edin — LexborHTMLParser(resp.content.decode("latin-1")) — böylece her iki motor da 'café éè' sonucunu doğru verir. Pratikte, selectolax’a her zaman bir str verin, ham UTF-8 olmayan bytes değil. README bunu açıkça söylemiyor.
Üretim boyutları (tek gözlem, o yüzden yön gösterici olarak değerlendirin)
Aşağıdaki sonuçları üç kez değil, bir kez ölçtüm; bu yüzden bunları kesin rakam değil, sinyal olarak işaretliyorum.
Thread ölçeklemesi en ilginç olanı. 1 MB sayfayı dört thread üzerinde 48 kez ayrıştırdığımda, selectolax yaklaşık 3.5-3.9x wall-clock hızlanma gösterdi — bu, C ayrıştırma sırasında GIL’i bırakan bir kütüphanenin tipik izidir — buna karşılık BeautifulSoup(lxml) thread’li çalıştırmada birkaç kat yavaşladı; bu da işin GIL üzerinde seri hale gelmesinin imzası. lxml ise ortada kaldı ve sonuç kesinleşmedi. Python’ın girdiği free-threading döneminde, BeautifulSoup’un aksine thread’ler arasında paralelleşen selectolax ayrıştırması, geçici de olsa, gerçek bir avantajdır. Yine de bu tek sayfa boyutunda tek bir thread sayısı; mekanizma ise C kodunu enstrümante ederek doğruladığım bir şey değil, varsayım.
Bellek sızıntısına gelince: 1 MB boyutta 2.000 ayrıştır-çıkar-at döngüsü boyunca üç parser’ın hiçbiri sızıntıdaki gibi doğrusal RSS artışı göstermedi — her biri sınırlı bir çalışma kümesi bandında dengelendi. Bu sonucu özellikle güvenilir buluyorum, çünkü aynı ölçüm aracından bilinen bir sızıntı örneğini geçirdim ve olması gerektiği gibi +198 MB’ye kadar çıktı; bu da aracın sızıntıyı görebildiğini, sadece parser’larda bulamadığını kanıtlıyor. Sahip olduğu ağacın kapsamı dışına taşmış bir node handle da kullanılabilir kaldı, segfault olmadı. Bunların hepsi tek gözlem; hiçbiri saatler süren soak testi değil.
selectolax nerede konumlanır, nerede topu başkasına bırakır?
Yukarıdakilerin hepsi tek bir iş hakkında: elinizde zaten bulunan HTML’i hızlı biçimde yapılandırılmış veriye dönüştürmek. selectolax bu işte çok iyi. Ama bilinçli olarak yapmadığı şeyler de var: sayfayı çekmek, JavaScript render etmek, proxy döndürmek, CAPTCHA çözmek ya da hangi elemanların önemli olduğuna karar vermek. Bunların hepsi hâlâ sizin kodunuzda. selectolax ayrıştırma katmanıdır; bundan fazlasıymış gibi davranmaz.
İşte bu çizgide, yönetilen bir veri çıkarma servisi parser’ın yerine geçmekten çok onun üstünde konumlanır. Fetch-render-anti-bot-extract yığınını kendiniz kurup sürdürmek istemiyorsanız, Thunderbit bunu API, MCP server ve CLI olarak sunar — POST /distill bir sayfayı temiz Markdown’a dönüştürür, POST /extract ise şemaya eşleşen yapılandırılmış JSON döndürür; JavaScript render ve anti-bot işlemleri sizin yerinize halledilir. Bu, problemin farklı bir katmanıdır: Ham HTML elinizdeyken ve kendi kontrolünüz altında hızlı ayrıştırma istediğinizde selectolax’a yönelirsiniz; çekme ve çıkarma işini size bırakmayan bir şey içinse Thunderbit’in API, MCP server veya CLI yaklaşımı daha uygundur. Bu bir değiş-tokuş değil; aynı yığının farklı bir yüksekliğidir.
Web Verisi Çıkarmak İçin Thunderbit’i Deneyin
Artılar, eksiler ve kimlerin gerçekten kullanması gerektiği
selectolax’ın kazandığı yerler:
- Gerçekçi parse+extract işlerinde BeautifulSoup’tan yaklaşık 12-17x hızlı; sayfa boyutu üç mertebe değişse de istikrarlı.
- Hafif bellek kullanımı (lxml sınıfı, BeautifulSoup’tan yaklaşık 1.5-1.8x daha az) ve yaklaşık 14 ms’lik import süresi.
- lxml’yi zorlayan girdilerde daha dayanıklı: boş içerik, yalnızca boşluk ve aşırı derin iç içe yapılar.
:has(),:is(),:where(), büyük/küçük harf duyarsız attribute’lar ve yalnızca Lexbor’a özgü:lexbor-contains()dahil modern CSS desteği.Nonegüvenli okuma/yazma DOM’u: eksik öğeler exception yerineNoneveya[]döndürür ve ağacı gerçekten değiştirip yeniden seri hale getirebilirsiniz.- Aktif bakım (v0.4.10, 2026 ortası) ve zahmetsiz kurulum.
Kazandığı yerler değil:
- lxml’den geniş anlamda daha hızlı değil — tam görevde berabere, saf parse adımında da benim ölçümümde geride.
- XPath yok ve
::text/::attr()yok — XPath’e dayalı scraper’lar için sert bir göç duvarı. - İki sessiz veri kaybı tuzağı var: Lexbor’da
<template>içeriği ve.text()üzerinden UTF-8 olmayan bytes. - Modest backend eski nesil ve
:dir()geldiğinde SIGABRT ile çöküyor. - Buradaki tüm rakamlar tek platformdan (macOS arm64, Python 3.14) ve geçicidir.
Peki selectolax kullanmalı mısınız? Evet, eğer lxml seviyesinde bir ayrıştırma hızını, daha dostane ve None güvenli bir API ile ve boş/bozuk girdilerde belirgin şekilde daha iyi davranışla istiyorsanız — ve CSS ile sınırlı çalışmayı kabul ediyorsanız. Kod tabanınız XPath üzerine kuruluysa, yeniden yazma maliyeti gerçektir; bunu dürüstçe tartmalısınız. Ve “tek başına en hızlı parser”ı arıyorsanız, bu benchmark’ın dürüst cevabı şu: selectolax ile lxml o kadar yakın ki karar kriteri ham hız değil, ergonomi ve sağlamlık olmalı. Zaten bir araç seçmek için daha iyi sebep de budur.
Web Verisi Çıkarmak İçin Thunderbit’i Deneyin Get Started Free
Sık Sorulan Sorular
selectolax, BeautifulSoup’tan daha mı hızlı?
Evet, açık şekilde — gerçekçi bir parse+extract görevinde BeautifulSoup(html.parser)’dan yaklaşık 12-17x, BeautifulSoup(lxml)’dan ise yaklaşık 10-14x daha hızlı; 1 KB’den 10 MB’ye kadar istikrarlı kalıyor (macOS arm64, Python 3.14). Sık kullanılan “4-5x” ifadesi, html.parser karşısındaki farkı küçümsüyor.
selectolax, lxml’den daha mı hızlı? Genel olarak hayır. Tam parse+extract görevinde 100 KB ve 1 MB boyutlarında başabaş gidiyorlar; selectolax yalnızca 10 MB sayfada öne çıkıyor. Saf ayrıştırmada ise bu makinede lxml yaklaşık %33-34 daha hızlıydı — tek platformlu olduğu için bunu kesin hüküm değil, kendi donanımınızda doğrulamanız gereken bir sonuç olarak değerlendirin.
Lexbor mu Modest mi kullanmalıyım?
Hemen her durumda Lexbor — README’nin önerdiği, aktif olarak bakımı yapılan ve daha kapsamlı CSS desteği sunan motor budur. Tek istisna, içeriğini <template> etiketleri içinde saklayan sayfalardır; burada Lexbor spes’e uygun şekilde o içeriği atar, Modest ise tesadüfen tutar. Modest’in ayrıca :dir() üzerinde interpreter’ı doğrudan çökertebilmesi gibi keskin yanları vardır.
selectolax XPath destekliyor mu?
Hayır. Hiçbir backend xpath() metodu sunmaz — selectolax yalnızca CSS odaklıdır. Scraper’larınız XPath’e bağlıysa, göç etmek seçicileri yeniden yazmak anlamına gelir; lxml veya parsel tabanlı bir yapıdan selectolax’a geçişin en büyük tek maliyeti budur.
selectolax çıktım neden bozuk ya da eksik öğeli geliyor?
İki yaygın sebep var. Eğer metinler replacement karakterlerle ya da eksik aksanlarla dönüyorsa, muhtemelen ham UTF-8 olmayan bytes gönderdiniz — ayrıştırmadan önce bunları str’e decode edin (resp.content.decode("latin-1")). Eğer modern bir sitede bağlantılar ya da öğeler eksikse, bunlar Lexbor backend’inin içine girmediği <template> etiketlerinin içinde olabilir; o sayfa için Modest’e ya da başka bir parser’a geçin.


