Unlimited Plugins, WordPress themes, videos & courses! Unlimited asset downloads! From $16.50/m
Advertisement
  1. Code
  2. Python

Kỹ thuật Scraping Trang web trong Python bằng Beautiful Soup: Cơ bản

by
Difficulty:IntermediateLength:MediumLanguages:
This post is part of a series called Scraping Webpages in Python with Beautiful Soup.
Scraping Webpages in Python With Beautiful Soup: Search and DOM Modification

Vietnamese (Tiếng Việt) translation by Dai Phong (you can also view the original English article)

Trong một bài viết trước, tôi đã hướng dẫn cho bạn cách sử dụng mô-đun Requests để truy cập các trang web bằng Python. Hướng dẫn đó đã đề cập đến rất nhiều chủ đề như tạo các yêu cầu GET/POST và tải về các nội dung như hình ảnh hoặc tập tin PDF bằng lập trình. Một điều còn thiếu trong hướng dẫn đó là về kỹ thuật scraping (trích xuất nội dung) trang web mà bạn đã truy cập bằng Requests để trích xuất thông tin mà bạn cần.

Trong hướng dẫn này, bạn sẽ được tìm hiểu về Beautiful Soup, một thư viện Python để trích xuất dữ liệu từ các tập tin HTML. Trọng tâm của hướng dẫn này là học các kiến ​​thức cơ bản của thư viện, và các chủ đề nâng cao sẽ được đề cập trong hướng dẫn tiếp theo. Xin lưu ý rằng hướng dẫn này sử dụng Beautiful Soup 4 cho tất cả các ví dụ.

Cài đặt

Bạn có thể cài đặt Beautiful Soup 4 bằng pip. Tên gói là beautifulsoup4. Nó sẽ làm việc trên cả Python 2 và Python 3.

Nếu bạn chưa cài đặt pip trên hệ thống của mình, bạn có thể trực tiếp tải về tarball nguồn của Beautiful Soup 4 và cài đặt nó bằng setup.py.

BeautifulSoup ban đầu được đóng gói như là code của Python 2. Khi bạn cài đặt nó để sử dụng với Python 3, nó sẽ tự động cập nhật sang code của Python 3. Code sẽ không được chuyển đổi trừ khi bạn cài đặt gói. Dưới đây là một số lỗi phổ biến mà bạn có thể bắt gặp:

  • ImportError "No module named HTMLParser" xảy ra khi bạn chạy phiên bản Python 2 của code Python 3.
  • ImportError "No module named html.parser" xảy ra khi bạn chạy phiên bản Python 3 của code Python 2.

Cả hai lỗi trên có thể được khắc phục bằng cách gỡ cài đặt và cài đặt lại Beautiful Soup.

Cài đặt Parser

Trước khi thảo luận về sự khác biệt giữa các parser khác nhau mà bạn có thể sử dụng cùng với Beautiful Soup, hãy viết code để tạo ra một soup.

Đối tượng BeautifulSoup có thể nhận hai đối số. Đối số đầu tiên là markup thật sự, và đối số thứ hai là parser mà bạn muốn sử dụng. Các parser khác nhau là: html.parser, lxmlhtml5lib. lxml có hai phiên bản, một HTML parser và một XML parser.

html.parser là một parser được tích hợp sẵn, và nó không hoạt động tốt trong các phiên bản cũ của Python. Bạn có thể cài đặt các parser khác bằng các lệnh sau:

Parser lxml rất nhanh và có thể được sử dụng để nhanh chóng phân tích HTML. Mặt khác, parser html5lib rất chậm, nhưng nó cũng cực kỳ dễ dùng. Dưới đây là một ví dụ về việc sử dụng từng parser này:

Những sự khác biệt được chỉ ra trong ví dụ trên chỉ có vấn đề khi bạn phân tích HTML không hợp lệ. Tuy nhiên, hầu hết HTML trên web không đúng định dạng, và nắm được những khác biệt này sẽ giúp bạn gỡ lỗi một số lỗi phân tích và quyết định parser nào bạn muốn sử dụng trong một dự án. Nói chung, parser lxml là một lựa chọn rất tốt.

Các Đối tượng trong Beautiful Soup

Beautiful Soup phân tích tài liệu HTML đã cho thành một cây các đối tượng Python. Có bốn đối tượng Python chính mà bạn cần biết: Tag, NavigableString, BeautifulSoupComment.

Đối tượng Tag chỉ về một thẻ XML hoặc HTML thật sự trong tài liệu. Bạn có thể truy cập vào tên của thẻ bằng tag.name. Bạn cũng có thể đặt tên thành một cái gì đó khác. Thay đổi tên sẽ được hiển thị trong markup do Beautiful Soup tạo ra.

Bạn có thể truy cập các thuộc tính khác nhau như class và id của thẻ bằng tag['class']tag['id'] tương ứng. Bạn cũng có thể truy cập vào toàn bộ từ điển của các thuộc tính bằng tag.attrs. Bạn cũng có thể thêm, xóa hoặc sửa đổi các thuộc tính của thẻ. Các thuộc tính như class của một phần tử có thể lấy nhiều giá trị được lưu trữ dưới dạng một danh sách.

Văn bản bên trong một thẻ được lưu trữ như là một NavigableString trong Beautiful Soup. Nó có một vài phương thức hữu ích như replace_with("string") để thay thế văn bản trong một thẻ. Bạn cũng có thể chuyển đổi một NavigableString thành unicode bằng cách sử dụng unicode().

Beautiful Soup cũng cho phép bạn truy cập các comment trong một trang web. Các comment này được lưu trữ dưới dạng một đối tượng Comment, về cơ bản cũng là NavigableString.

Bạn đã học về đối tượng BeautifulSoup trong phần trước. Nó được sử dụng để đại diện cho toàn bộ tài liệu. Vì nó không phải là một đối tượng thực tế, nên nó không có bất kỳ tên hoặc thuộc tính nào.

Lấy Tiêu đề, Heading và Liên kết

Bạn có thể trích xuất tiêu đề trang và dữ liệu khác rất dễ dàng bằng Beautiful Soup. Hãy trích xuất trang Wikipedia về Python. Trước tiên, bạn sẽ phải lấy cho được markup của trang web bằng cách sử dụng code sau đây dựa trên hướng dẫn về mô-đun Requests để truy xuất các trang web.

Bây giờ bạn đã tạo ra soup, bạn có thể lấy tiêu đề của trang web bằng cách sử dụng code sau:

Bạn cũng có thể trích xuất các thông tin khác của trang web như heading hoặc đoạn văn đầu tiên, các lớp của chúng, hoặc thuộc tính id.

Tương tự, bạn có thể lặp qua tất cả các liên kết hoặc heading con trong một tài liệu bằng code sau:

Điều hướng trên DOM

Bạn có thể điều hướng trên cây DOM bằng các tên thẻ thông thường. Việc móc nối các tên thẻ có thể giúp bạn điều hướng cây được sâu hơn. Ví dụ, bạn có thể lấy được liên kết đầu tiên trong đoạn đầu của trang Wikipedia cho trước bằng soup.p.a. Tất cả các liên kết trong đoạn văn đầu tiên có thể được truy cập bằng soup.p.find_all('a').

Bạn cũng có thể truy xuất tất cả các con của một thẻ thành một danh sách sử dụng tag.contents. Để có được các con tại một chỉ mục cụ thể, bạn có thể sử dụng tag.contents[index]. Bạn cũng có thể lặp qua các con của một thẻ bằng thuộc tính .children.

Cả .children.contents chỉ hữu ích khi bạn muốn truy cập con trực tiếp hoặc cấp đầu tiên của một thẻ. Để có được tất cả các con, bạn có thể sử dụng thuộc tính .descendants.

Bạn cũng có thể truy cập vào phần tử cha của một phần tử bằng thuộc tính .parent. Tương tự, bạn có thể truy cập vào tất cả các phần tử cha của một phần tử bằng cách sử dụng thuộc tính .parents. Phần tử cha của thẻ cấp cao nhất <html> chính là đối tượng BeautifulSoup, và cha của nó là None.

Bạn có thể truy cập phần tử anh chị em trước và sau của một phần tử bằng các thuộc tính .previous_sibling.next_sibling.

Đối với hai phần tử để được là anh chị em, chúng cần phải có cùng một phần tử cha. Điều này có nghĩa là con đầu tiên của một phần tử sẽ không có anh chị em trước. Tương tự, phần tử con cuối cùng của một phần tử sẽ không có anh chị em kế tiếp. Trong các trang web thật sự, các anh chị em trước và tiếp theo của một phần tử có lẽ sẽ là một ký tự xuống dòng.

Bạn cũng có thể lặp qua tất cả các anh chị em của một phần tử bằng .previous_siblings.next_siblings.

Bạn có thể tìm thấy phần tử ngay sau phần tử hiện tại bằng thuộc tính .next_element. Để truy cập vào phần tử xuất hiện ngay trước phần tử hiện tại, sử dụng thuộc tính .previous_element.

Tương tự, bạn có thể lặp qua tất cả các phần tử trước và sau phần tử hiện tại bằng cách sử dụng .previous_elements.next_elements tương ứng.

Tóm tắt

Sau khi đọc xong hướng dẫn này, bạn đã hiểu rõ hơn về sự khác biệt chính giữa các parser HTML khác nhau. Bây giờ bạn còn có thể điều hướng trên một trang web và trích xuất các dữ liệu quan trọng. Điều này có thể hữu ích khi bạn muốn phân tích tất cả các đề mục hoặc liên kết trên một trang web nhất định.

Trong phần tiếp theo của loạt bài này, bạn sẽ được học cách sử dụng thư viện Beautiful Soup để tìm kiếm và sửa đổi DOM.

Advertisement
Advertisement
Advertisement
Advertisement
Looking for something to help kick start your next project?
Envato Market has a range of items for sale to help get you started.