Skip to main content

Penulis

Aditya Sundar - Universiti Waseda

Abstrak

Projek ini membangunkan web crawler yang direka untuk meneroka laman web secara sistematik dan menjana senarai URL yang komprehensif, tanpa mengira ketersediaan sitemap. Crawler mengendalikan kedua-dua kandungan statik dan dinamik, menjejaki rujukan luaran, dan beroperasi dengan cekap pada perkakasan yang terhad. Keupayaan Utama:
  • Crawling tak segerak dengan keserentakan boleh dikonfigurasi
  • Penemuan URL berasaskan BFS untuk liputan sistematik
  • Penjejakan dan analisis rujukan luaran
  • Sokongan kandungan dinamik melalui Playwright
  • Penyimpanan berterusan berasaskan SQLite

1. Pengenalan

Web crawling membolehkan sistem automatik melayari laman web dan mengumpul data. Walaupun sitemap menyediakan senarai URL berstruktur, tidak semua laman web mempunyainya. Crawler ini:
  • Berfungsi pada tapak dengan atau tanpa sitemap
  • Menjana sitemap luaran (URL yang merujuk domain lain)
  • Berjalan pada perkakasan spek rendah tanpa proksi
  • Mengendalikan laman web berskala besar dengan cekap

2. Metodologi

2.1 Tindanan Teknologi

TeknologiTujuan
PythonBahasa utama
aiohttpPermintaan HTTP tak segerak
BeautifulSoupPenghuraian HTML dan pengekstrakan pautan
asyncioPelaksanaan kod serentak
SQLitePenyimpanan URL berterusan
PlaywrightRendering kandungan dinamik
fake_useragentMengelakkan pengesanan bot

2.2 Aliran Kerja Crawler

  1. Permulaan: Normalisasi URL permulaan, semak robots.txt, cipta jadual pangkalan data
  2. Pengambilan URL: Permintaan batch tak segerak dengan kelewatan
  3. Pengekstrakan Pautan: Huraikan tag anchor, normalisasikan URL
  4. Penyimpanan Data: SQLite untuk URL, ralat, domain luaran
  5. Keserentakan: Had boleh dikonfigurasi (lalai: 100 serentak)
  6. Penyelesaian: Berhenti apabila tiada URL baharu atau had dicapai

2.3 Pematuhan Robots.txt

def check_robots_txt(url, timeout=5, retry_count=3):
    robots_url = f"{parsed_url.scheme}://{parsed_url.netloc}/robots.txt"
    rp.set_url(robots_url)

    for attempt in range(retry_count):
        try:
            response = requests.get(robots_url, timeout=timeout)
            if response.status_code < 400:
                rp.parse(response.text.splitlines())
                return
        except requests.Timeout:
            print(f"Timeout, mencuba semula...")

    # Lalai kepada membenarkan crawl jika robots.txt tidak tersedia
    rp.parse(['User-agent: *', 'Disallow:'])

2.4 Algoritma BFS

Crawler menggunakan Breadth-First Search untuk meneroka URL:
  • Memproses semua URL pada kedalaman semasa sebelum bergerak lebih dalam
  • Memastikan liputan sistematik peringkat demi peringkat
  • Membenarkan penyambungan semula jika terganggu

2.5 Pengendalian Ralat

Jenis RalatTindakan
404, 403, 400Langkau (tiada cuba semula)
429Tunggu untuk header Retry-After
500, 502, 503Cuba semula dengan kelewatan
TimeoutCuba semula sehingga 3 kali

3. Keputusan

3.1 Statistik Crawling

Jenis Laman WebURL DalamanRujukan Luaran
Tapak Hiburan 147,8707,010,999
Tapak Permainan 2143,0583,027,460
Tapak Siaran Akhbar99,2432,136,887
Tapak Berita 6117,1641,895,515
Tapak Kerajaan 128,84155,700
Tapak Pendidikan 150,45828,328
Jumlah:
  • URL Dalaman: 1,121,407
  • Rujukan Luaran: 18,957,040
Carta Nisbah URL

Nisbah URL Luaran kepada Dalaman mengikut Jenis Laman Web

Tapak hiburan/berita mempunyai nisbah rujukan luaran yang lebih tinggi daripada tapak kerajaan, mencerminkan strategi kandungan yang berbeza.

3.2 Analisis Ralat

Jenis RalatBilangan
Status 40443,611
Status 50329,555
Ralat penyahkodan3,271
Sekatan Robots.txt2,696
Ralat lain124,261
Cuba semula maksimum dicapai11,994
Pautan sebenarnya dilangkau: 62,050

3.3 Pandangan SEO

  • Tapak media: Nisbah rujukan luaran yang tinggi mungkin meningkatkan kredibiliti
  • Tapak kerajaan: Tumpuan pada pautan dalaman adalah sesuai
  • Pendekatan seimbang disyorkan untuk kebanyakan tapak

4. Pengoptimuman

Pengehadan Kadar

connector = aiohttp.TCPConnector(limit=100)  # Boleh diselaraskan
Had yang lebih rendah mencegah ralat 429 tetapi memperlahankan crawling.

Kandungan Dinamik (SPA)

Playwright mengendalikan kandungan yang dirender JavaScript:
async def scrape_all_links(start_url):
    async with async_playwright() as p:
        browser = await p.chromium.launch(headless=False)
        page = await browser.new_page()

Normalisasi URL

  • Buang fragmen
  • Menyatukan skema (HTTPS sahaja)
  • Buang garis miring trailing
  • Pangkalan data mencegah crawling duplikat

5. Hala Tuju Masa Depan

  1. Sokongan proksi: Mengurangkan risiko sekatan IP
  2. Perkakasan lebih baik: Mengendalikan crawl yang lebih besar
  3. Integrasi Scrapy: Memanfaatkan ciri rangka kerja yang teguh
  4. Analisis graf: Memetakan hubungan laman web menggunakan embeddings

Rujukan

  1. aiohttp - Klien/pelayan HTTP tak segerak untuk Python
  2. BeautifulSoup - Pustaka penghuraian HTML/XML
  3. Playwright - Rangka kerja automasi pelayar
  4. SQLite - Enjin pangkalan data ringan