HuuTuan .Info

Chia sẻ ATTT - CNTT - Đồ họa

Lấy nội dung của website bằng Beautiful Soup trong Python

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.

1
$ pip install beautifulsoup4
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.
1
$ python setup.py install
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.
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.
1
2
3
from bs4 import BeautifulSoup
soup = BeautifulSoup("<html><p>This is <b>invalid HTML</p></html>", "html.parser")
Đố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.parserlxml và html5liblxml 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:
1
2
$ pip install lxml
$ pip install html5lib
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:
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
soup = BeautifulSoup("<html><p>This is <b>invalid HTML</p></html>", "html.parser")
print(soup)
# <html><p>This is <b>invalid HTML</b></p></html>
soup = BeautifulSoup("<html><p>This is <b>invalid HTML</p></html>", "lxml")
print(soup)
# <html><body><p>This is <b>invalid HTML</b></p></body></html>
soup = BeautifulSoup("<html><p>This is <b>invalid HTML</p></html>", "xml")
print(soup)
# <?xml version="1.0" encoding="utf-8"?>
# <html><p>This is <b>invalid HTML</b></p></html>
soup = BeautifulSoup("<html><p>This is <b>invalid HTML</p></html>", "html5lib")
print(soup)
# <html><head></head><body><p>This is <b>invalid HTML</b></p></body></html>
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.
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: TagNavigableStringBeautifulSoup và Comment.
Đố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'] và 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.
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.
1
2
3
4
5
import requests
from bs4 import BeautifulSoup
req = requests.get('https://en.wikipedia.org/wiki/Python_(programming_language)')
soup = BeautifulSoup(req.text, "lxml")
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:
1
2
3
4
5
6
7
8
soup.title
# <title>Python (programming language) - Wikipedia</title>
soup.title.name
# 'title'
soup.title.string
# 'Python (programming language) - Wikipedia'
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.
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
soup.h1
# <h1 class="firstHeading" id="firstHeading" lang="en">Python (programming language)</h1>
soup.h1.string
# 'Python (programming language)'
soup.h1['class']
# ['firstHeading']
soup.h1['id']
# 'firstHeading'
soup.h1.attrs
# {'class': ['firstHeading'], 'id': 'firstHeading', 'lang': 'en'}
soup.h1['class'] = 'firstHeading, mainHeading'
soup.h1.string.replace_with("Python - Programming Language")
del soup.h1['lang']
del soup.h1['id']
soup.h1
# <h1 class="firstHeading, mainHeading">Python - Programming Language</h1>
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:
1
2
3
4
for sub_heading in soup.find_all('h2'):
    print(sub_heading.text)
     
# all the sub-headings like Contents, History[edit]...
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 và .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.
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
print(soup.p.contents)
# [<b>Python</b>, ' is a widely used ',.....the full list]
print(soup.p.contents[10])
# <a href="/wiki/Readability" title="Readability">readability</a>
for child in soup.p.children:
    print(child.name)
# b
# None
# a
# None
# a
# None
# ... and so on.
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.
01
02
03
04
05
06
07
08
09
10
11
print(soup.p.parent.name)
# div
for parent in soup.p.parents:
    print(parent.name)
# div
# div
# div
# body
# html
# [document]
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 và .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 và .next_siblings.
01
02
03
04
05
06
07
08
09
10
11
soup.head.next_sibling
# '\n'
soup.p.a.next_sibling
# ' for '
soup.p.a.previous_sibling
# ' is a widely used '
print(soup.p.b.previous_sibling)
# None
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 và .next_elements tương ứng.
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.

Nguồn: code.tutsplus.com

0 Response to "Lấy nội dung của website bằng Beautiful Soup trong Python"

Post a Comment

Nội Quy Khi Comment:
» Các bài comment phải nghiêm túc, không dung tục, không spam.
» Nội dung phải liên quan tới chủ đề bài viết.
» Những nhận xét spam sẽ bị xóa.
» Sử dụng tài khoản Google để được trợ giúp.
» Nặc danh thường không được chào đón.
Note : Hãy để lại nhận xét bên dưới bạn nhé !

Quảng Cáo TOP

Quảng Cáo TOP 1

Quảng Cáo TOP 2

Quảng Cáo TOP