Đăng ký SPRINGMEBLOG để tiếp thu kiến thức hiệu quả hơn!

Forgot Password

Đăng ký SPRINGMEBLOG để tiếp thu kiến thức hiệu quả hơn!

Cảm ơn bạn đã đăng ký tài khoản Springmeweb!

Vui lòng kiểm tra Email, click vào Link để kích hoạt tài khoản.

Beautiful Soup 4 (Part 1)

BY: Nguyen-Ngoan  |   June 4, 2018  |  
Python
  • 0

Beautiful Soup 4

Mục đích: Parse HTML, XML và Website scraping

Bạn muốn parse HTML, XML hay đơn giản là muốn scraping dữ liệu từ một website nào đó với ngôn ngữ Python? Trên Viblo cũng có một số bài của Anh Tranngoc về Scraping và Crawling dữ liệu từ một website nào đó với module Scrapy như: Kỹ thuật scraping và crawling Web nâng cao với Scrapy và SQLAlchemy hay Scraping và crawling Web với Scrapy và SQLAlchemy. Nay mình cũng xin phép giới thiệu một module cũng có thể scraping dữ liệu giống Scrapy nhưng nó nhẹ và đơn giản hơn cho những yêu cầu không đòi hỏi sự phức tạp như Scrapy, đó là Beautiful Soup. Chúng ta cùng đi tìm hiểu nó nhé!

Cài đặt

Trước tiên, chúng ta có thể kiểm tra xem trên máy của mình đã cài module này chưa hoặc nếu đã cài rồi, chúng ta xem mình đã ở phiên bản mới nhất chưa bằng 1 đoạn code ngắn trên terminal như sau:

python -c "import bs4; print(bs4.__version__);"

Sau khi thử đoạn code trên, nếu máy bạn đã cài rồi thì nó sẽ xuất hiện phiên bản của module BeautifulSoup. Còn không, bạn sẽ nhận được một lỗi như sau:

Traceback (most recent call last):
  File "<string>", line 1, in <module>
ImportError: No module named bs4

Để cài Beautiful Soup 4, bạn có bốn cách là thông qua APT, PIP, EasyInstall hoặc thông qua source. Mình sẽ đưa ra cả bốn cách cài để bạn có thể lựa chọn cho phù hợp với sở thích của mình nhé

  • Qua APT: sudo apt-get install python-bs4
  • Qua PIP: sudo pip install beautifulsoup4
  • Qua EasyInstall: sudo easy_install beautifulsoup4
  • Qua source:
    • Vào trang download của Beautiful Soup tại đây rồi download phiên bản mà bạn muốn sử dụng.
    • Xả nén source bằng lệnh: tar -vfx <Path to BeautifulSoup tar file>
    • Thay đổi thư mục hiện thời bằng lệnh: cd <Path to BeautifulSoup source folder>/
    • Cài đặt: python setup.py install

Nếu tất cả cách trên đều không thể cài đặt được, thì bạn vẫn có thể sử dụng nó bằng cách copy thư mục bs4 ở phần cài đặt bằng source vào thư mục source code của bạn rồi sử dụng như bình thường !

Cài đặt parser

Beautiful Soup hỗ trợ thư viện HTML parser mặc định của Python và một số thư viện của bên thứ ba. Ví dụ như lxml parse hoặc html5lib parser. Mình sẽ hướng dẫn các bạn cài đặt cả 2 thư viện này nhé !

HTML5Lib

Để cài đặt HTML5Lib, bạn có thể làm theo 1 trong 3 cách:

  • Thông qua APT:
    • sudo apt-get install python-html5lib
  • Thông qua PIP:
    • pip install html5lib
  • Thông qua EasyInstall
    • easy_install html5lib

LXML

Để có thể cài đặt được LXML parser, bạn cần phải có 3 package sau: libxml2-dev, libxslt1-dev và python-dev.

  • Cài đặt các required packages:
    • sudo apt-get install libxml2-dev libxslt1-dev python-dev
  • Cài đặt LXML parser:
    • Thông qua APT:
      • sudo apt-get install python-lxml
    • Thông qua PIP:
      • pip install lxml
    • Thông qua EasyInstall:
      • easy_install lxml

Cách sử dụng các parser

  • Python html.parser
    • BeautifulSoup(markup, "html.parser")
  • LXML HTML parser
    • BeautifulSoup(markup, "lxml")
  • LXML XLM parser
    • BeautifulSoup(markup, "lxml-xml") hoặc BeautifulSoup(markup, "xml")
  • HTML5Lib
    • BeautifulSoup(markup, "html5lib")

Chuẩn bị nguyên liệu

Để thử Beautiful Soup, chúng ta sẽ tạo một file HTML với tên bs4.html trong thư mục tmp với nội dung như sau:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
    <link rel="stylesheet" href="css.css" type="text/css">
</head>
<body>
    <!-- Items list -->
    <div class="items-list">
        <div class="item pull-right">
            <p class="title">Item 001</p>
            <p class="price">Price: 01$</p>
            <p><a href="#">Buy</a></p>
        </div>
        <div class="item pull-right">
            <p class="title">Item 002</p>
            <p class="price">Price: 02$</p>
            <p><a href="#">Buy</a></p>
        </div>
        <div class="item pull-right">
            <p class="title">Item 003</p>
            <p class="price">Price: 03$</p>
            <p><a href="#">Buy</a></p>
        </div>
    </div>
    <!-- End of items list -->
</body>
</html>

Making the soup

Sau khi đã có đầy đủ nguyên liệu và dụng cụ rồi, chúng ta cùng nhau đi chế biến món soup nhé ). Để parser một tài liệu, bạn chỉ cần import BeautifulSoup từ thư viện bs4 rồi truyền file handle hoặc một chuỗi HTML (XML) vào constructor của BeautifulSoup là có thể sử dụng được ngay. Xem ra món này nấu khá đơn giản đấy nhỉ ?

from bs4 import BeautifulSoup

from_file_handle = BeautifulSoup(open('/tmp/bs4.html'))
from_string = BeautifulSoup('<html>data</html>')

Ở BeautifulSoup constructor, nếu bạn không truyền tên của parser mà bạn muốn sử dụng ở tham số thứ 2 thì mặc định nó sẽ sử dụng parser tốt nhất đang có sẵn trên hệ thống của bạn.

OK, bây giờ chúng ta sẽ đi vào chi tiết 1 chút về Beautiful Soup nhé. Trước khi đi vào chi tiết, chúng ta sẽ tạo 1 file code python đơn giản là đọc dữ liệu từ file bs4.html mà chúng ta đã chuẩn bị từ trước để sử dụng nhé. Trong file code này, mình có sử dụng module pdb (Python Debugger) để tiện cho việc debug code của chúng ta trên terminal. Nếu có thể, mình sẽ giới thiệu module pdb này trong bài viết tiếp theo của series PyMOTM này ! Còn việc sử dụng parser nào thì tùy bạn quyết định nhé. Mình sẽ dùng HTML5Lib !

#!/usr/bin/env python

from bs4 import BeautifulSoup
import pdb

html_dom = BeautifulSoup(open('/tmp/bs4.html'), 'html5lib')

# Dừng lại để chúng ta debug
pdb.set_trace();

Let's go (gogo)!

Các loại object của Beautiful Soup

Beautiful Soup sẽ chuyển đổi tài liệu HTML sang Python tree object. Nhưng bạn chỉ cần quan tâm 4 loại object là: Tag, NavigableString, BeautifulSoup và Comment thôi nhé !

Tag

Là một HTML (XML) tag

(Pdb) title_tag = html_dom.find('title')
(Pdb) type(title_tag)
<class 'bs4.element.Tag'>
(Pdb)

Name

Tên của tag. Bạn có thể lấy ra bằng cách sử dụng .name

(Pdb) title_tag.name
u'title'

Bạn cũng có thể thay đổi tên của tag bằng cách gán cho nó 1 cái tên

(Pdb) title_tag.name = 'blockquote'
(Pdb) title_tag
<blockquote>Document</blockquote>

Attributes

Một tag có thể có một hoặc nhiều attribute. Bạn có thể lấy giá trị của một attribute như sau:

(Pdb) link_tag = html_dom.find('link')
(Pdb) link_tag['rel']
[u'stylesheet']

Hoặc bạn cũng có thể lấy ra tất cả các attribute của 1 tag bằng .attrs. Dữ liệu trả ra là 1 dictionary:

(Pdb) link_tag.attrs
{u'href': u'css.css', u'type': u'text/css', u'rel': [u'stylesheet']}

Bạn cũng có thể thêm/sửa/xóa một attribute của tag:

(Pdb) link_tag['href'] = 'lorem.css'
(Pdb) link_tag
<link href="lorem.css" rel="stylesheet" type="text/css"/>
(Pdb) del link_tag['rel']
(Pdb) link_tag
<link href="lorem.css" type="text/css"/>
(Pdb) link_tag['media'] = 'all'
(Pdb) link_tag
<link href="lorem.css" media="all" type="text/css"/>

Multi-valued attributes

Ở HTML4 nó định nghĩa khá nhiều attribute được phép nhiều hơn một giá trị (các giá trị cách nhau 1 space). Nhưng sang HTML5 thì nó đã được định nghĩa lại chỉ còn một vài attribute được phép nhiều hơn 1 giá trị là class, rel, rev, accept-charset, headers và accesskey. Kết quả trả về là một danh sách các giá trị của attribute đó (nếu nó thuộc các attribute được liệt kê ở trên), hoặc là một string (nếu attribute đó không thuộc danh sách được liệt kê ở trên):

(Pdb) items = html_dom.select('.items-list .item')
(Pdb) items[0]['class']
[u'item', u'pull-right']

Bạn cũng có thể thêm/sửa/xóa một giá trị trong danh sách các giá trị của attribute đó:

(Pdb) del items[0]['class'][0]
(Pdb) items[0]['class']
[u'pull-right']
(Pdb) items[0]['class'] = ['lorem', 'lipsum']
(Pdb) items[0]['class']
['lorem', 'lipsum']
(Pdb) items[0]['class'][0] = 'lorem_updated'
(Pdb) items[0]['class']
['lorem_updated', 'lipsum']

NavigableString

Là nội dung text của tag đó. NavigableString giống như một Python Unicode string, ngoại trừ việc nó hỗ trợ bạn một số tính năng như duyệt và tìm kiếm (sẽ được giới thiệu ở bài tiếp theo). Bạn cũng có thể convert nó sang kiểu Unicode string bằng function unicode()

(Pdb) title_tag.string
u'Document'
(Pdb) type(title_tag.string)
<class 'bs4.element.NavigableString'>
(Pdb) unicode_title = unicode(title_tag.string)
(Pdb) type(unicode_title)
<type 'unicode'>

Bạn không thể sửa nội dung văn bản của 1 tag bằng cách trực tiếp, nhưng có thể thay thế nó thông qua function replace_with():

(Pdb) title_tag.string
u'Document'
(Pdb) title_tag.string.replace_with('PyMOTM: BeautifulSoup4')
u'Document'
(Pdb) title_tag
<title>PyMOTM: BeautifulSoup4</title>

Bài viết cũng đã khá dài rồi mà chúng ta mới chỉ đi chưa được một nửa của Beautiful Soup, nên mình xin phép tạm dừng tại đây nhé. Phần 2 mình sẽ giới thiệu về việc duyệt và tìm kiếm nhé !

Viblo.asia

Please Share This With

ĐĂNG KÝ ĐỂ TIẾP THU KIẾN THỨC HIỆU QUẢ HƠN

ABOUT SPRINGMEBLOG

Springmeblog.com giới thiệu các bài viết về chủ đề KINH DOANH, PHÁT TRIỂN SỰ NGHIỆP, QUẢN LÝ CON TRẺ.

Các bài viết của Springmeblog được chọn lọc kỹ từ các bài viết English của các chuyên gia giỏi trên thế giới để mang lại nguồn kiến thức HỮU ÍCH nhất và THIẾT THỰC nhất có thể áp dụng ngay vào công việc và cuộc sống.

Springmeblog.com được thiết kế nhằm mang đến sự tiếp thu kiến thức một cách HIỆU QUẢ nhất. Mỗi bài viết English được giới thiệu có công cụ TỪ ĐIỂN TÍCH HỢP hỗ trợ đọc hiểu. Cùng với các công cụ LƯU BÀI VIẾT, TẠO GHI CHÚ cho mỗi bài viết, springmeblog hỗ trợ cho việc HỌC TẬP SUỐT ĐỜI qua tiêu chí ĐỌC ĐỂ LÀM và HỌC ĐỂ LÀM ĐƯỢC.

© 2018 SPRINGMEWEB. DESIGIN BY SPRINGMEWEB