Lập Trình Web Scraping Với Python: Hướng Dẫn Thực Hành Dành Cho Người Mới Bắt Đầu

Lập Trình Web Scraping Với Python: Hướng Dẫn Dành Cho Người Mới Bắt Đầu

Trình duyệt Scraping Không Có Rác hiển thị các trang công cộng được điều khiển bởi JavaScript cho các quy trình làm việc web scraping Python cần đầu ra từ trình duyệt thay vì HTML ban đầu.

Tóm tắt

  • Một trình thu thập dữ liệu Python cơ bản có bốn giai đoạn: yêu cầu, phân tích, chọn, và lưu trữ. Giữ mỗi giai đoạn tách biệt để dễ dàng xác định lỗi.
  • Bắt đầu trên một trang ổn định mà bạn được phép truy cập. Kiểm tra phản hồi trước khi viết bộ chọn hoặc vòng lặp.
  • Các bộ phân tích HTML không thực thi JavaScript. Sử dụng một đường dẫn dựa trên trình duyệt khi nội dung yêu cầu chỉ xuất hiện sau khi các kịch bản trang chạy.
  • Các bộ chọn là một phần của hợp đồng dữ liệu. Ưu tiên các thẻ ngữ nghĩa, nhãn, thuộc tính ổn định, và mẫu URL hơn là tên lớp được tạo ra.
  • Scraping có trách nhiệm là có giới hạn và minh bạch. Tôn trọng các quy tắc truy cập, điều khoản, quyền riêng tư, bản quyền, và tải hoạt động đặt lên một trang web.

Ý Nghĩa Của Web Scraping Với Python

Web scraping với Python có nghĩa là truy cập một tài nguyên web và chuyển đổi nội dung trả về thành dữ liệu có cấu trúc. Một trình thu thập nhỏ có thể đọc một trang HTML và trích xuất tiêu đề của nó. Một bộ thu thập sản xuất có thể hiển thị JavaScript, theo dõi phân trang được phép, xác thực bản ghi, lưu trữ nguồn gốc, và giám sát sự thay đổi trong cấu trúc nguồn.

Python là một lựa chọn phổ biến vì nó có các thư viện HTTP, phân tích, trình duyệt, dữ liệu, và lưu trữ trưởng thành. Ngôn ngữ chỉ là một lớp. Một trình thu thập đáng tin cậy cũng cần một lược đồ mục tiêu rõ ràng, một chính sách nguồn, các bộ chọn phù hợp với các tính năng ổn định của trang, và các kiểm tra phân biệt dữ liệu thực từ các trang lỗi hoặc các shell rỗng.

Bắt đầu với nội dung công cộng và một mục tiêu hẹp. “Thu thập tiêu đề và URL chuẩn từ một trang được phép” dễ dàng xác minh hơn là “scrape toàn bộ trang web.” Phiên bản hẹp phơi bày cơ chế mà không khuyến khích việc thu thập không giới hạn.

Mô Hình Scraping Bốn Giai Đoạn

Giai đoạnCâu hỏiCông cụ Python điển hình
Yêu cầuMáy chủ có trả lại tài nguyên mong muốn không?urllib.request hoặc Requests
Phân tíchPhản hồi có thể được biểu diễn dưới dạng cây tài liệu không?html.parser, Beautiful Soup, hoặc lxml
ChọnCác phần tử nào ánh xạ đến các trường mong muốn?CSS selectors, tìm kiếm thẻ, thuộc tính, hoặc XPath
Lưu trữLàm thế nào sẽ lưu các bản ghi sạch và nguồn gốc?csv, json, sqlite3, hoặc một khách hàng cơ sở dữ liệu

Không nên gộp các giai đoạn này thành một hàm không rõ trong khi học. In trạng thái, loại nội dung, URL cuối cùng, và một bản xem trước phản hồi ngắn trước khi phân tích. Sau khi phân tích, kiểm tra các phần tử đã chọn trước khi viết đầu ra. Các ranh giới giai đoạn khiến nó rõ ràng liệu một tiêu đề bị thiếu đến từ truy cập mạng, việc hiển thị JavaScript, thay đổi bộ chọn, hay dọn dẹp dữ liệu.

Người Tài liệu urllib.request của Python bao gồm giao diện yêu cầu của thư viện tiêu chuẩn. Tài liệu của bên thứ ba Requests cung cấp một API HTTP thân thiện hơn với các phiên, tiêu đề, giải mã, proxy, và thời gian chờ.

Một Trình Thu Thập Đầu Tiên Chạy Được

Ví dụ này chỉ sử dụng thư viện tiêu chuẩn của Python và trang trình bày ổn định tại example.com. Nó truy cập trang, kiểm tra loại phản hồi, phân tích tiêu đề đầu tiên, và in ra một bản ghi JSON. Mã không có thông tin xác thực và không có cách làm việc xung quanh truy cập trang cụ thể.

import json
from html.parser import HTMLParser
from urllib.request import Request, urlopen


class FirstHeadingParser(HTMLParser):
    def __init__(self):
        super().__init__()
        self.in_h1 = False
        self.heading_parts = []

    def handle_starttag(self, tag, attrs):
        if tag == "h1" and not self.heading_parts:
            self.in_h1 = True

    def handle_endtag(self, tag):
        if tag == "h1":
            self.in_h1 = False

    def handle_data(self, data):
        if self.in_h1:
            self.heading_parts.append(data.strip())


url = "https://example.com/"
request = Request(url, headers={"User-Agent": "LearningScraper/1.0"})

with urlopen(request, timeout=15) as response:
    content_type = response.headers.get_content_type()
    html_text = response.read().decode(response.headers.get_content_charset() or "utf-8")

if content_type != "text/html":
    raise ValueError(f"Expected HTML, received {content_type}")

parser = FirstHeadingParser()
parser.feed(html_text)
record = {"url": url, "heading": " ".join(parser.heading_parts)}
print(json.dumps(record, indent=2))

Tiêu đề mong đợi là “Example Domain.” Kịch bản sử dụng một tác nhân người dùng mô tả, thời gian chờ, kiểm tra loại nội dung, và giải mã rõ ràng. Những chi tiết đó dù nhỏ, nhưng chúng thiết lập thói quen quan trọng khi mục tiêu trở nên khó đoán hơn.

Sử Dụng Requests và Beautiful Soup

Requests và Beautiful Soup làm cho quy trình tương tự trở nên ngắn hơn. Requests truy cập phản hồi; Beautiful Soup phân tích HTML và hỗ trợ lựa chọn theo kiểu CSS. Tài liệu chính thức của Beautiful Soup giải thích cách chọn bộ phân tích, tìm kiếm thẻ, các bộ chọn CSS, và điều hướng cây.

import requests
from bs4 import BeautifulSoup

url = "https://example.com/"
response = requests.get(
    url,
    headers={"User-Agent": "LearningScraper/1.0"},
    timeout=15,
)
response.raise_for_status()

soup = BeautifulSoup(response.text, "html.parser")
heading = soup.select_one("h1")

if heading is None:
    raise ValueError("The page did not contain an h1 element")

print({"url": response.url, "heading": heading.get_text(" ", strip=True)})

Cài đặt các phụ thuộc trong một môi trường ảo với python -m pip install requests beautifulsoup4. Đính kèm các phiên bản trong một dự án thực tế để môi trường mới giải quyết cùng một bộ phụ thuộc. Giữ mã yêu cầu và phân tích tách biệt khi bộ thu thập thông tin phát triển.

Chọn Bộ chọn Bền vững

Các phần tử ngữ nghĩa

Một tiêu đề, bài viết, thời gian, nhãn giá, hoặc liên kết chuẩn thường truyền đạt ý nghĩa rõ ràng hơn là một lớp bao bọc hiển thị.

Các thuộc tính ổn định

Các thuộc tính dữ liệu đã được tài liệu, thuộc tính mục, nhãn có thể truy cập và ID có thể sống lâu hơn các lớp kiểu đã tạo.

Mẫu URL

Các liên kết có hình dạng đường dẫn bền vững có thể hỗ trợ khám phá khi các thẻ hiển thị thay đổi bố cục.

Dữ liệu trang có cấu trúc

Dữ liệu JSON công khai hoặc dữ liệu có cấu trúc nhúng có thể bảo tồn tốt hơn tên trường so với đánh dấu trình bày khi được phép truy cập.

Một bộ chọn nên cụ thể như trường yêu cầu và không hơn thế. Một chuỗi sáu lớp lồng nhau rất dễ bị phá vỡ. Một div bộ chọn trần là quá rộng. Lưu một mẫu HTML nhỏ từ một nguồn được ủy quyền và kiểm tra rằng các trường bắt buộc vẫn hiện diện trong khi các trường tùy chọn có thể là null.

Không bao giờ giả định rằng phần tử khớp đầu tiên là chính xác. Kiểm tra nhãn, ngữ cảnh cha, đơn vị, và URL chuẩn. Nếu một giá có thể đại diện cho một đợt bán hàng, giá niêm yết hoặc trả góp, sơ đồ nên bảo tồn sự phân biệt thay vì ép mọi giá trị vào một trường.

HTML tĩnh so với Các trang Động

Yêu cầu và urllib nhận phản hồi từ máy chủ nhưng không chạy JavaScript của trang. Nếu trình duyệt hiển thị dữ liệu mà không có trong response.text, trang có thể lấy hoặc xây dựng nội dung đó sau khi tải. Xác nhận sự khác biệt bằng cách xem nguồn ban đầu và tài liệu đã được kết xuất.

Một trang động không phải lúc nào cũng yêu cầu tự động hóa trình duyệt. Trang có thể gọi một điểm cuối JSON công khai mà trang web tài liệu hoặc phơi bày cho trình duyệt. Khi việc sử dụng trực tiếp được phép và ổn định, dữ liệu có cấu trúc có thể dễ dàng xác thực hơn. Khi nội dung phụ thuộc vào tương tác, quản lý phía khách hàng hoặc trạng thái hiển thị, hãy sử dụng một trình duyệt và chờ đợi một phần tử có ý nghĩa hơn là một độ trễ mơ hồ.

Trình duyệt Thu thập Thông tin không có Scrapeless cung cấp phiên trình duyệt được quản lý cho việc kết xuất và tương tác JavaScript. Một ứng dụng Python có thể kết nối qua một khuôn khổ trình duyệt hỗ trợ hoặc tích hợp Scrapeless, thu thập nội dung đã được kết xuất và sau đó tái sử dụng các giai đoạn phân tích và xác thực bình thường của nó.

Dọn dẹp và Lưu trữ Hồ sơ

Các chuỗi đã trích xuất thường cần bình thường hóa. Xóa các khoảng trắng xung quanh, bảo tồn các khoảng không gian nội bộ có ý nghĩa, phân tích số với tiền tệ hoặc đơn vị của chúng, và giữ giá trị nguồn thô khi việc chuyển đổi có thể mất thông tin. Đại diện cho các trường tùy chọn vắng mặt dưới dạng null thay vì một không hoặc đơn yêu cầu trống.

Một hồ sơ nên mang tính nguồn gốc: URL nguồn, URL chuẩn khi có, giá trị trường, và thời gian hoặc phiên bản nguồn liên quan đến tập dữ liệu. Đối với một dự án nhỏ, JSON Lines là thuận tiện vì mỗi dòng là một đối tượng độc lập. CSV hoạt động cho các hồ sơ phẳng. SQLite thêm loại, chỉ mục, các ràng buộc tính duy nhất, và truy vấn mà không cần một máy chủ.

Xác thực trước khi lưu trữ. Các trường bắt buộc nên có mặt, URL nên là tuyệt đối, các giá trị liệt kê nên khớp với sơ đồ, và các khoảng số nên hợp lý. Xóa trùng lặp với một định danh nguồn ổn định, không phải là tiêu đề hiển thị có thể thay đổi.

Thu thập Thông tin Có trách nhiệm và Bảo trì

Việc thu thập thông tin có trách nhiệm bắt đầu với sự cho phép và phạm vi. Xem xét các điều khoản của trang, chỉ thị robots, luật áp dụng, bản quyền, nghĩa vụ về quyền riêng tư, và bất kỳ API chính thức nào. Chỉ thu thập các trường công khai cần thiết cho mục đích đã nêu. Không truy cập tài liệu riêng tư, bảo mật, hạn chế, hoặc đã xác thực mà không có sự cho phép.

Ràng buộc khối lượng công việc. Lưu các trang không thay đổi ở nơi thích hợp, tránh các yêu cầu lặp không cần thiết, và giữ mức độ đồng thời ở mức khiêm tốn. Xác định khách hàng khi ngữ cảnh cho phép. Bảo vệ dữ liệu cá nhân đã thu thập và xác định các quy tắc giữ gìn và xóa trước khi thu thập.

Khả năng bảo trì đến từ các hợp đồng có thể quan sát. Ghi lại URL cuối cùng, trạng thái, loại nội dung, số lượng bộ chọn, và các thất bại xác thực mà không lưu trữ bí mật. Thêm các bài kiểm tra cho HTML đại diện. Khi một bộ chọn thay đổi, kiểm tra trang mới và cập nhật quy tắc trích xuất một cách có chủ đích thay vì che giấu thất bại bằng cách xuất ra trống.

Từ Kịch bản đến Luồng Sản xuất

Một bộ thu thập thông tin sản xuất tách biệt việc lập lịch, thu mua, phân tích, xác thực, lưu trữ, và giám sát. Mỗi giai đoạn có đầu vào và đầu ra rõ ràng. Điều này làm cho việc thay thế một yêu cầu tĩnh bằng một kết xuất trình duyệt mà không cần viết lại xác thực trường trở nên khả thi, hoặc thay đổi lưu trữ mà không chạm đến các bộ chọn.

  1. Xác định sơ đồ và phạm vi nguồn được phép.
  2. Nắm bắt một phản hồi đại diện và xác minh rằng đó là trang dự kiến.
  3. Viết các bộ chọn và xác thực cấp trường.
  4. Thêm phân trang ràng buộc chỉ sau khi một trang hoạt động.
  5. Lưu lại nguồn gốc và các định danh ổn định với mọi hồ sơ.
  6. Giám sát các trường vắng mặt, số lượng bộ chọn, loại phản hồi, và sự thay đổi nguồn.
  7. Xem xét chính sách truy cập và giữ gìn dữ liệu khi quy trình làm việc mở rộng.

Giữ các mẫu nhỏ trong khi học. Một bộ thu thập thông tin tạo ra mười hồ sơ chính xác, có thể truy dấu là một nền tảng tốt hơn so với một cái thu thập hàng ngàn chuỗi không được xác thực.

Kết luận

Thu thập thông tin trên web với Python là một chuỗi các giai đoạn có thể quan sát: yêu cầu, phân tích, chọn, xác thực, và lưu trữ. Bắt đầu với một trang tĩnh được phép, sử dụng các bộ chọn ổn định, bảo tồn nguồn gốc, và kiểm tra hồ sơ mà bạn tạo ra. Thêm một trình duyệt chỉ khi nội dung yêu cầu kết xuất hoặc tương tác, và giữ các ràng buộc truy cập, quyền riêng tư, khối lượng công việc, và bảo trì rõ ràng khi dự án phát triển.

Sẵn sàng để vượt ra ngoài HTML tĩnh?

Kết nối quy trình làm việc dữ liệu Python của bạn với kết xuất trình duyệt được quản lý cho các trang công khai động.

Đăng ký ngay hôm nay và nhận $5 tín dụng miễn phíkhông yêu cầu thẻ tín dụng.

Nhận $5 tín dụng của bạn →

Câu hỏi thường gặp

Thu thập thông tin trên web với Python có hợp pháp không?

Việc thu thập dữ liệu trên web không được điều chỉnh bởi một quy tắc chung nào. Tính hợp pháp phụ thuộc vào quyền tài phán, dữ liệu, phương pháp truy cập, điều khoản hợp đồng, bản quyền, quyền riêng tư và mục đích sử dụng. Làm việc với dữ liệu công khai, xem xét điều khoản của trang và chỉ dẫn dành cho robot, ưu tiên các API chính thức khi phù hợp, và tham khảo ý kiến của luật sư có chuyên môn cho các dự án quan trọng.

Beautiful Soup và Requests có chạy JavaScript không?

Không. Requests lấy phản hồi HTTP, và Beautiful Soup phân tích HTML hoặc XML mà nó nhận được. Cả hai đều không thực thi JavaScript trên trang. Sử dụng một điểm cuối có cấu trúc được cấp phép hoặc quy trình làm việc với trình duyệt khi nội dung yêu cầu chỉ xuất hiện sau khi được kết xuất hoặc tương tác.

Người mới bắt đầu nên thu thập dữ liệu gì trước tiên?

Bắt đầu với một trang trình diễn ổn định hoặc một trang web rõ ràng cho phép mục đích sử dụng. Trích xuất một hoặc hai trường từ một trang, xác minh chúng và lưu lại một bản ghi nhỏ. Tránh dữ liệu tài khoản, dữ liệu cá nhân và việc thu thập rộng trong khi học.

Làm thế nào để tôi biết được một bộ chọn có đáng tin cậy không?

Một bộ chọn đáng tin cậy phản ánh nghĩa của trường và vẫn ổn định trên các trang đại diện. Ưu tiên các thẻ ngữ nghĩa, nhãn, thuộc tính được tài liệu hóa, và các mẫu URL bền vững. Kiểm tra các trường yêu cầu và tùy chọn so với các mẫu được cấp phép đã lưu và thất bại một cách rõ ràng khi các phần tử yêu cầu biến mất.

Khi nào thì một trình thu thập dữ liệu Python nên sử dụng một trình duyệt được quản lý?

Sử dụng trình duyệt được quản lý khi nội dung mục tiêu yêu cầu kết xuất JavaScript, cuộn trang, điều hướng hoặc tương tác mà một phản hồi HTTP trực tiếp không thể cung cấp. Giữ việc phân tích, xác minh, nguồn gốc và chính sách truy cập trong ứng dụng Python ngay cả khi việc thu thập chuyển sang dịch vụ trình duyệt.

Tài liệu tham khảo