DEV Community

Cover image for Tìm orphan page và đo internal link graph của website bằng Python
Onic Ai
Onic Ai

Posted on Originally published at onic.vn

Tìm orphan page và đo internal link graph của website bằng Python

Trang mồ côi (orphan page) là trang không có link nội bộ nào trỏ tới. Nó vẫn có thể được Google tìm thấy qua sitemap, nhưng thiếu tín hiệu để hiểu trang thuộc chủ đề nào và quan trọng đến đâu, còn người đọc không có đường vào. Bài này viết một crawler nhỏ để dựng đồ thị link nội bộ, tìm trang mồ côi và xem trang nào nhận nhiều link nhất.

Google đọc link thế nào

Theo hướng dẫn về link của Google Search Central, Google chỉ chắc chắn đọc được link viết bằng thẻ <a> có thuộc tính href. Nút bấm chạy JavaScript không có href, hoặc link nằm trong ảnh mà không có chữ thay thế, đều có thể bị bỏ qua. Google cũng nói mọi trang quan trọng nên có link từ ít nhất một trang khác trên website.

Crawl và dựng đồ thị

import requests
from bs4 import BeautifulSoup
from urllib.parse import urljoin, urlparse
from collections import defaultdict

def crawl(goc: str, gioi_han: int = 500):
    mien = urlparse(goc).netloc
    hang, da_xem = [goc], set()
    vao = defaultdict(set)      # url -> tập trang trỏ tới nó
    anchor = defaultdict(list)  # url -> danh sách anchor
    while hang and len(da_xem) < gioi_han:
        url = hang.pop(0)
        if url in da_xem:
            continue
        da_xem.add(url)
        r = requests.get(url, timeout=15)
        if "text/html" not in r.headers.get("content-type", ""):
            continue
        soup = BeautifulSoup(r.text, "html.parser")
        for a in soup.select("main a[href], article a[href]"):
            dich = urljoin(url, a["href"]).split("#")[0]
            if urlparse(dich).netloc != mien or dich == url:
                continue
            vao[dich].add(url)
            anchor[dich].append(a.get_text(" ", strip=True))
            if dich not in da_xem:
                hang.append(dich)
    return da_xem, vao, anchor
Enter fullscreen mode Exit fullscreen mode

Selector main a, article a chỉ lấy link trong thân bài. Link trong menu, footer và sidebar xuất hiện trên mọi trang, nên nếu tính cả thì mọi trang đều "có link" và trang mồ côi thật bị che mất.

Tìm trang mồ côi

Crawler chỉ đi được tới trang có link, nên trang mồ côi thật sự sẽ không bao giờ xuất hiện trong da_xem. Phải so với một danh sách khác, thường là sitemap:

import xml.etree.ElementTree as ET

def url_trong_sitemap(sitemap_url: str) -> set:
    xml = requests.get(sitemap_url, timeout=15).text
    ns = {"s": "http://www.sitemaps.org/schemas/sitemap/0.9"}
    return {loc.text.strip() for loc in ET.fromstring(xml).findall(".//s:loc", ns)}

def mo_coi(sitemap: set, vao: dict) -> list:
    return sorted(u for u in sitemap if not vao.get(u))
Enter fullscreen mode Exit fullscreen mode

Với WordPress dùng Yoast, sitemap là file chỉ mục trỏ tới nhiều sitemap con, nên cần đọc đệ quy.

Trang nào nhận nhiều link nhất

def xep_hang(vao: dict, n: int = 15):
    return sorted(((len(v), u) for u, v in vao.items()), reverse=True)[:n]
Enter fullscreen mode Exit fullscreen mode

So danh sách này với danh sách trang quan trọng về kinh doanh. John Mueller của Google khuyên nhìn internal link một cách chiến lược: cấu trúc link nên phản ánh trang nào anh em quan tâm nhất. Nếu trang dịch vụ chính nằm cuối bảng còn trang "giới thiệu" đứng đầu, cấu trúc đang nói ngược với ưu tiên.

Soát anchor

Từ anchor[url], đếm các anchor rỗng (link ảnh không alt), anchor chung như "xem thêm", và anchor lặp. Một trang mà mọi link trỏ về dùng đúng một cụm từ là dấu hiệu không tự nhiên. Khung chia anchor theo 5 nhóm, cùng năm chiến thuật xây liên kết nội bộ cho người viết nội dung, có trong bài Internal link là gì trên Onic.vn.

Lưu ý khi chạy

  • Crawl chậm, có time.sleep giữa các request, và chỉ chạy trên website của chính mình.
  • Chuẩn hóa URL (dấu gạch chéo cuối, tham số) trước khi so, nếu không một trang sẽ bị đếm thành nhiều trang.
  • Không cần gắn nofollow cho link nội bộ; nếu crawler thấy nhiều link nội bộ có rel="nofollow", đó là chỗ cần xem lại.

Bài gốc: https://onic.vn/kien-thuc/internal-link-la-gi/

Top comments (0)