Xây dựng Trình trích xuất danh sách bài viết blog bằng Python

Bài viết này sẽ hướng dẫn cách xây dựng một công cụ đơn giản bằng Python để trích xuất danh sách các bài viết từ một blog cá nhân, bao gồm tiêu đề và URL tương ứng. Chúng ta sẽ bắt đầu bằng việc thiết lập môi trường Python cơ bản, cài đặt các thư viện cần thiết, sau đó đi sâu vào logic phân tích và thu thập dữ liệu từ trang web.

Thiết lập môi trường Python

Để bắt đầu, bạn cần cài đặt Python trên hệ thống của mình. Phiên bản được khuyến nghị là Python 3.x (ví dụ: 3.9 trở lên).

Cài đặt Python

Bạn có thể tải xuống trình cài đặt Python từ trang web chính thức: https://www.python.org/downloads/. Hãy chọn phiên bản ổn định mới nhất phù hợp với hệ điều hành của bạn. Trong quá trình cài đặt, hãy đảm bảo chọn tùy chọn "Add Python to PATH" để dễ dàng sử dụng Python từ dòng lệnh.

Xác minh cài đặt

Sau khi cài đặt, mở một cửa sổ Command Prompt (hoặc Terminal) mới và gõ lệnh sau để kiểm tra xem Python đã được cài đặt và cấu hình PATH đúng cách hay chưa:

python --version

Bạn sẽ thấy phiên bản Python hiện ra (ví dụ: `Python 3.9.x`). Tiếp theo, kiểm tra công cụ quản lý gói `pip`:

pip --version

Nếu `pip` hoạt động, môi trường Python của bạn đã sẵn sàng.

Chuẩn bị thư viện cần thiết

Để thực hiện việc trích xuất dữ liệu web, chúng ta cần cài đặt hai thư viện Python chính:

  • requests: Dùng để gửi các yêu cầu HTTP đến trang web và nhận về nội dung HTML.
  • BeautifulSoup4 (bs4): Dùng để phân tích cú pháp HTML và trích xuất dữ liệu mong muốn một cách dễ dàng.
  • lxml: Một parser nhanh mà BeautifulSoup4 có thể sử dụng.

Sử dụng pip để cài đặt các thư viện này:

pip install requests beautifulsoup4 lxml

Nếu bạn không cài đặt lxml, BeautifulSoup có thể báo lỗi khi cố gắng phân tích cú pháp HTML.

Phân tích cấu trúc trang web

Trước khi viết mã, điều quan trọng là phải kiểm tra cấu trúc HTML của trang blog mục tiêu để xác định các phần tử chứa thông tin chúng ta muốn trích xuất (tiêu đề và liên kết bài viết). Sử dụng công cụ kiểm tra phần tử của trình duyệt (thường là F12) để xem mã nguồn.

Ví dụ, giả sử cấu trúc HTML của mỗi bài viết trên trang blog cá nhân trông như sau:

<div class="postTitle">
    <a class="postTitle2" href="https://www.cnblogs.com/your-blog/post-url.html">
        <span>Tiêu đề bài viết của bạn</span>
    </a>
</div>

Từ cấu trúc này, chúng ta có thể thấy rằng:

  • Mỗi bài viết được bao bọc trong một thẻ <div> có thuộc tính class="postTitle".
  • Bên trong <div class="postTitle"> là một thẻ <a> có thuộc tính class="postTitle2", chứa cả tiêu đề và URL.
  • Tiêu đề bài viết là văn bản bên trong thẻ <a> (hoặc <span> bên trong <a>).
  • URL bài viết nằm trong thuộc tính href của thẻ <a>.

Thực hiện Trích xuất danh sách bài viết

Dựa trên phân tích trên, chúng ta sẽ viết mã Python để thực hiện các bước sau:

  1. Gửi yêu cầu GET đến từng trang của blog.
  2. Sử dụng BeautifulSoup để phân tích cú pháp nội dung HTML nhận được.
  3. Tìm tất cả các phần tử <div>class="postTitle".
  4. Trong mỗi <div> đó, trích xuất tiêu đề và URL từ thẻ <a>.
  5. Lưu thông tin này vào một file Markdown.

Dưới đây là mã nguồn Python:

import requests
from bs4 import BeautifulSoup
import os

# Hàm để trích xuất dữ liệu từ một trang blog cụ thể
def scrape_blog_page(page_number):
    """
    Trích xuất tiêu đề và URL bài viết từ một trang blog nhất định.
    Args:
        page_number (int): Số trang cần trích xuất.
    Returns:
        list: Danh sách các tuple (tiêu đề, URL) của các bài viết trên trang.
    """
    base_url = 'https://www.cnblogs.com/caoleiCoding/default.html?page={}'
    target_url = base_url.format(page_number)
    blog_entries = []

    print(f"Đang yêu cầu trang: {target_url}")
    try:
        # Gửi yêu cầu GET đến trang web
        response = requests.get(target_url, timeout=10)
        response.raise_for_status()  # Ném lỗi HTTP cho các phản hồi lỗi (4xx hoặc 5xx)
    except requests.exceptions.RequestException as e:
        print(f"Lỗi khi yêu cầu trang {page_number}: {e}")
        return []

    # Phân tích cú pháp HTML bằng BeautifulSoup và parser lxml
    soup = BeautifulSoup(response.text, 'lxml')

    # Tìm tất cả các div có class='postTitle'
    for post_container in soup.find_all('div', class_='postTitle'):
        # Tìm thẻ 'a' chứa liên kết và tiêu đề bên trong mỗi 'postTitle' div
        post_link_element = post_container.find('a', class_='postTitle2')

        if post_link_element:
            # Lấy văn bản tiêu đề (nội dung của thẻ 'a') và loại bỏ khoảng trắng thừa
            title = post_link_element.text.strip()
            # Lấy URL từ thuộc tính 'href' của thẻ 'a'
            article_url = post_link_element['href']

            if title and article_url: # Đảm bảo tiêu đề và URL không rỗng
                blog_entries.append((title, article_url))
        # else:
            # print(f"Không tìm thấy liên kết bài viết trong div postTitle trên trang {page_number}")

    return blog_entries

if __name__ == "__main__":
    output_filename = 'danh-sach-bai-viet-blog.md'
    # Đặt tổng số trang blog muốn trích xuất.
    # Bạn có thể cần kiểm tra blog của mình để biết tổng số trang thực tế.
    total_pages_to_process = 60 # Ví dụ: trích xuất 60 trang đầu tiên

    all_blog_posts = []

    # Lặp qua từng trang và thu thập dữ liệu
    for page_num in range(1, total_pages_to_process + 1): # Trang thường được đánh số từ 1
        posts_on_current_page = scrape_blog_page(page_num)
        all_blog_posts.extend(posts_on_current_page)

    # Ghi danh sách các bài viết đã thu thập được vào file Markdown
    print(f"\nĐang ghi {len(all_blog_posts)} bài viết vào '{output_filename}'...")
    with open(output_filename, 'w', encoding='utf-8') as md_file:
        entry_index = 1
        for post_title, post_url in all_blog_posts:
            md_file.write(f"{entry_index}. [{post_title}]({post_url})\n")
            entry_index += 1

    print(f"Quá trình hoàn tất. Danh sách bài viết đã được lưu vào '{output_filename}'.")

Đoạn mã trên sẽ tạo ra một file Markdown có tên danh-sach-bai-viet-blog.md chứa danh sách các bài viết dưới dạng liên kết có thể nhấp được, với mỗi mục được đánh số thứ tự.

Thẻ: python web scraping BeautifulSoup requests HTML Parsing

Đăng vào ngày 21 tháng 7 lúc 19:11