Cách làm việc với dữ liệu web bằng cách sử dụng yêu cầu và món súp đẹp mắt với Python 3
Web cung cấp cho ta nhiều dữ liệu hơn bất kỳ ai trong ta có thể đọc và hiểu, vì vậy ta thường muốn làm việc với thông tin đó theo chương trình để hiểu rõ về nó. Đôi khi, dữ liệu đó được người tạo trang web cung cấp cho ta thông qua.csv
hoặc các file giá trị được phân tách bằng dấu phẩy hoặc thông qua API (Giao diện lập trình ứng dụng). Những lần khác, ta cần tự mình thu thập văn bản từ web. Hướng dẫn này sẽ trình bày cách làm việc với các gói Python Request và Beautiful Soup để sử dụng dữ liệu từ các trang web. Mô-đun Yêu cầu cho phép bạn tích hợp các chương trình Python của bạn với các dịch vụ web, trong khi module Beautiful Soup được thiết kế để làm cho việc quét màn hình được thực hiện nhanh chóng. Sử dụng console tương tác Python và hai thư viện này, ta sẽ xem xét cách thu thập một trang web và làm việc với thông tin văn bản có sẵn ở đó.
Yêu cầu
Để hoàn thành hướng dẫn này, bạn cần một môi trường phát triển cho Python 3. Bạn có thể làm theo hướng dẫn thích hợp cho hệ điều hành của bạn có sẵn trong loạt bài Cách cài đặt và cài đặt môi trường lập trình local cho Python 3 hoặc Cách cài đặt Python 3 và Cài đặt Môi trường Lập trình trên Server Ubuntu 16.04 để cấu hình mọi thứ bạn cần.
Ngoài ra, bạn nên làm quen với:
- Control panel tương tác Python
- Nhập module trong Python 3
- Cấu trúc HTML và gắn thẻ
Với môi trường phát triển của bạn đã được cài đặt và các khái niệm lập trình Python này, hãy bắt đầu làm việc với Yêu cầu và Súp đẹp.
Yêu cầu cài đặt
Hãy bắt đầu bằng cách kích hoạt môi trường lập trình Python 3 của ta . Đảm bảo rằng bạn đang ở trong folder chứa môi trường của bạn và chạy lệnh sau:
- . my_env/bin/activate
Để làm việc với các trang web, ta cần yêu cầu trang đó. Thư viện Yêu cầu cho phép bạn sử dụng HTTP trong các chương trình Python của bạn theo cách mà con người có thể đọc được.
Với môi trường lập trình của ta được kích hoạt, ta sẽ cài đặt Yêu cầu bằng pip:
- pip install requests
Trong khi thư viện Yêu cầu đang được cài đặt, bạn sẽ nhận được kết quả sau:
OutputCollecting requests Downloading requests-2.18.1-py2.py3-none-any.whl (88kB) 100% |████████████████████████████████| 92kB 3.1MB/s ... Installing collected packages: chardet, urllib3, certifi, idna, requests Successfully installed certifi-2017.4.17 chardet-3.0.4 idna-2.5 requests-2.18.1 urllib3-1.21.1
Nếu Yêu cầu đã được cài đặt trước đó, bạn sẽ nhận được phản hồi tương tự như sau từ cửa sổ terminal của bạn:
OutputRequirement already satisfied ...
Với các Yêu cầu được cài đặt vào môi trường lập trình của ta , ta có thể tiếp tục cài đặt module tiếp theo.
Cài đặt Beautiful Soup
Cũng giống như ta đã làm với Yêu cầu, ta sẽ cài đặt Beautiful Soup bằng pip. Phiên bản hiện tại của Beautiful Soup 4 có thể được cài đặt bằng lệnh sau:
- pip install beautifulsoup4
Sau khi chạy lệnh này, bạn sẽ thấy kết quả trông giống như sau:
OutputCollecting beautifulsoup4 Downloading beautifulsoup4-4.6.0-py3-none-any.whl (86kB) 100% |████████████████████████████████| 92kB 4.4MB/s Installing collected packages: beautifulsoup4 Successfully installed beautifulsoup4-4.6.0
Bây giờ cả Beautiful Soup và Request đều được cài đặt, ta có thể chuyển sang hiểu cách làm việc với các thư viện để xử lý các trang web.
Thu thập một trang web với các yêu cầu
Với hai thư viện Python mà ta sẽ sử dụng hiện đã được cài đặt, ta có thể tự làm quen với việc lướt qua một trang web cơ bản.
Trước tiên, hãy chuyển sang Control panel tương tác Python :
- python
Từ đây, ta sẽ nhập module Yêu cầu để ta có thể thu thập một trang web mẫu:
- import requests
-
Ta sẽ chỉ định URL (bên dưới) của trang web mẫu, mockturtle.html
cho url
biến :
- url = 'https://assets.digitalocean.com/articles/eng_python/beautiful-soup/mockturtle.html'
-
Tiếp theo, ta có thể gán kết quả của một yêu cầu của trang đó vào biến page
với request.get()
phương pháp . Ta chuyển URL của trang (được gán cho biến url
) vào phương thức đó.
- page = requests.get(url)
-
page
biến được chỉ định một đối tượng Phản hồi:
>>> page <Response [200]> >>>
Đối tượng Phản hồi ở trên cho ta biết thuộc tính status_code
trong dấu ngoặc vuông (trong trường hợp này là 200
). Thuộc tính này có thể được gọi một cách rõ ràng:
>>> page.status_code 200 >>>
Mã trả về là 200
cho ta biết rằng trang được download thành công. Các mã bắt đầu bằng số 2
thường cho biết thành công, trong khi các mã bắt đầu bằng số 4
hoặc 5
cho biết đã xảy ra lỗi. Bạn có thể đọc thêm về mã trạng thái HTTP từ Định nghĩa mã trạng thái của W3C .
Để làm việc với dữ liệu web, ta sẽ muốn truy cập nội dung dựa trên văn bản của file web. Ta có thể đọc nội dung phản hồi của server bằng page.text
(hoặc page.content
nếu ta muốn truy cập phản hồi theo byte).
- page.text
Khi ta nhấn ENTER
, ta sẽ nhận được kết quả sau:
Output'<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"\n "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">\n\n<html lang="en-US" xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">\n<head>\n <meta http-equiv="content-type" content="text/html; charset=us-ascii" />\n\n <title>Turtle Soup</title>\n</head>\n\n<body>\n <h1>Turtle Soup</h1>\n\n <p class="verse" id="first">Beautiful Soup, so rich and green,<br />\n Waiting in a hot tureen!<br />\n Who for such dainties would not stoop?<br />\n Soup of the evening, beautiful Soup!<br />\n Soup of the evening, beautiful Soup!<br /></p>\n\n <p class="chorus" id="second">Beau--ootiful Soo--oop!<br />\n Beau--ootiful Soo--oop!<br />\n Soo--oop of the e--e--evening,<br />\n Beautiful, beautiful Soup!<br /></p>\n\n <p class="verse" id="third">Beautiful Soup! Who cares for fish,<br />\n Game or any other dish?<br />\n Who would not give all else for two<br />\n Pennyworth only of Beautiful Soup?<br />\n Pennyworth only of beautiful Soup?<br /></p>\n\n <p class="chorus" id="fourth">Beau--ootiful Soo--oop!<br />\n Beau--ootiful Soo--oop!<br />\n Soo--oop of the e--e--evening,<br />\n Beautiful, beauti--FUL SOUP!<br /></p>\n</body>\n</html>\n' >>>
Ở đây ta thấy rằng toàn bộ văn bản của trang đã được in ra, với tất cả các thẻ HTML của nó. Tuy nhiên, nó khó đọc vì không có nhiều khoảng cách.
Trong phần tiếp theo, ta có thể tận dụng module Beautiful Soup để làm việc với dữ liệu dạng văn bản này theo cách thân thiện với con người hơn.
Bước qua một trang với món súp đẹp mắt
Thư viện Beautiful Soup tạo một cây phân tích cú pháp từ các trang HTML và XML đã được phân tích cú pháp (bao gồm các tài liệu có thẻ không đóng hoặc súp thẻ và đánh dấu không đúng định dạng khác). Chức năng này sẽ làm cho văn bản trang web dễ đọc hơn những gì ta đã thấy từ module Yêu cầu.
Để bắt đầu, ta sẽ nhập Beautiful Soup vào console Python:
- from bs4 import BeautifulSoup
-
Tiếp theo, ta sẽ chạy tài liệu page.text
thông qua module để cung cấp cho ta một đối tượng BeautifulSoup
- nghĩa là một cây phân tích cú pháp từ trang được phân tích cú pháp này mà ta sẽ nhận được từ việc chạy html.parser
hợp của Python trên HTML. Đối tượng được xây dựng đại diện cho tài liệu mockturtle.html
dưới dạng cấu trúc dữ liệu lồng nhau. Điều này được gán cho soup
biến.
- soup = BeautifulSoup(page.text, 'html.parser')
-
Để hiển thị nội dung của trang trên terminal , ta có thể in nó bằng phương thức prettify()
để biến cây phân tích cú pháp Beautiful Soup thành một chuỗi Unicode được định dạng độc đáo.
- print(soup.prettify())
Điều này sẽ hiển thị từng thẻ HTML trên dòng riêng của nó:
Output<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <html lang="en-US" xml:lang="en-US" xmlns="http://www.w3.org/1999/xhtml"> <head> <meta content="text/html; charset=utf-8" http-equiv="content-type"/> <title> Turtle Soup </title> </head> <body> <h1> Turtle Soup </h1> <p class="verse" id="first"> Beautiful Soup, so rich and green, <br/> Waiting in a hot tureen! <br/> Who for such dainties would not stoop? <br/> Soup of the evening, beautiful Soup! ... </html>
Trong kết quả kết quả ở trên, ta có thể thấy rằng có một thẻ trên mỗi dòng và các thẻ được lồng vào nhau do schemas cây được Beautiful Soup sử dụng.
Tìm bản sao của thẻ
Ta có thể extract một thẻ từ một trang bằng cách sử dụng phương pháp find_all
của Beautiful Soup. Kết quả sẽ trả về tất cả các version của một thẻ nhất định trong một tài liệu.
- soup.find_all('p')
Chạy phương thức đó trên đối tượng của ta sẽ trả về toàn bộ nội dung của bài hát cùng với các <p>
có liên quan và bất kỳ thẻ nào có trong thẻ được yêu cầu đó, ở đây bao gồm các thẻ ngắt dòng <br/>
:
Output[<p class="verse" id="first">Beautiful Soup, so rich and green,<br/> Waiting in a hot tureen!<br/> Who for such dainties would not stoop?<br/> Soup of the evening, beautiful Soup!<br/> Soup of the evening, beautiful Soup!<br/></p>, <p class="chorus" id="second">Beau--ootiful Soo--oop!<br/> ... Beau--ootiful Soo--oop!<br/> Soo--oop of the e--e--evening,<br/> Beautiful, beauti--FUL SOUP!<br/></p>]
Bạn sẽ nhận thấy trong kết quả ở trên rằng dữ liệu được chứa trong dấu ngoặc vuông [ ]
. Điều này nghĩa là nó là một kiểu dữ liệu danh sách Python.
Bởi vì nó là một danh sách, ta có thể gọi một mục cụ thể trong nó (ví dụ: phần tử <p>
thứ ba) và sử dụng phương thức get_text()
để extract tất cả văn bản từ bên trong thẻ đó:
- soup.find_all('p')[2].get_text()
Kết quả mà ta nhận được sẽ là những gì nằm trong phần tử <p>
thứ ba trong trường hợp này:
Output'Beautiful Soup! Who cares for fish,\n Game or any other dish?\n Who would not give all else for two\n Pennyworth only of Beautiful Soup?\n Pennyworth only of beautiful Soup?'
Lưu ý \n
ngắt dòng cũng được hiển thị trong chuỗi trả về ở trên.
Tìm thẻ theo lớp và ID
Các phần tử HTML tham chiếu đến các bộ chọn CSS như lớp và ID có thể hữu ích khi xem xét khi làm việc với dữ liệu web bằng Beautiful Soup. Ta có thể nhắm đến các lớp và ID cụ thể bằng cách sử dụng phương thức find_all()
và chuyển lớp và chuỗi ID làm đối số.
Đầu tiên, ta hãy tìm tất cả các trường hợp của chorus
trong lớp. Trong Beautiful Soup, ta sẽ gán chuỗi cho lớp cho đối số từ khóa class_
:
- soup.find_all(class_='chorus')
Khi ta chạy dòng trên, ta sẽ nhận được danh sách sau dưới dạng kết quả :
Output[<p class="chorus" id="second">Beau--ootiful Soo--oop!<br/> Beau--ootiful Soo--oop!<br/> Soo--oop of the e--e--evening,<br/> Beautiful, beautiful Soup!<br/></p>, <p class="chorus" id="fourth">Beau--ootiful Soo--oop!<br/> Beau--ootiful Soo--oop!<br/> Soo--oop of the e--e--evening,<br/> Beautiful, beauti--FUL SOUP!<br/></p>]
Hai phần được gắn thẻ <p>
với lớp chorus
được in ra terminal .
Ta cũng có thể chỉ định rằng ta chỉ muốn tìm kiếm chorus
lớp trong các <p>
, trong trường hợp nó được sử dụng cho nhiều thẻ:
- soup.find_all('p', class_='chorus')
Chạy dòng trên sẽ tạo ra kết quả tương tự như trước.
Ta cũng có thể sử dụng Beautiful Soup để nhắm đến các ID được liên kết với các thẻ HTML. Trong trường hợp này, ta sẽ gán chuỗi 'third'
cho id
đối số từ khóa:
- soup.find_all(id='third')
Khi ta chạy dòng trên, ta sẽ nhận được kết quả sau:
Output[<p class="verse" id="third">Beautiful Soup! Who cares for fish,<br/> Game or any other dish?<br/> Who would not give all else for two<br/> Pennyworth only of Beautiful Soup?<br/> Pennyworth only of beautiful Soup?<br/></p>]
Văn bản được liên kết với <p>
với id third
được in ra terminal cùng với các thẻ có liên quan.
Kết luận
Hướng dẫn này đưa bạn qua việc truy xuất một trang web bằng module Yêu cầu bằng Python và thực hiện một số thao tác quét sơ bộ dữ liệu văn bản của trang web đó để hiểu về Beautiful Soup.
Từ đây, bạn có thể tiếp tục tạo một chương trình cạo trang web sẽ tạo file CSV từ dữ liệu được thu thập từ web theo hướng dẫn Cách cạo các trang web với Beautiful Soup và Python 3 .
Các tin liên quan
Sử dụng Web worker một cách dễ dàng trong Vue.js với vue-worker2017-05-16
Cách cài đặt Icinga và Icinga Web trên Ubuntu 16.04
2017-05-05
Cách lưu trữ nhiều trang web với Nginx và HAProxy bằng LXD trên Ubuntu 16.04
2017-04-19
Cách bảo mật ứng dụng web nông dân của bạn bằng Let's Encrypt trên Ubuntu 16.04
2017-03-29
Xây dựng các thành phần web gốc với Vue.js
2017-03-16
Cách sử dụng OpenResty Web Framework cho Nginx trên Ubuntu 16.04
2017-02-28
Roundup: Thư viện thành phần ứng dụng web trên máy tính để bàn Vue.js - Cập nhật Q4 2017
2017-02-23
Cách cài đặt Django Web Framework trên Debian 8
2016-12-21
Cách triển khai ứng dụng web Falcon với Gunicorn và Nginx trên Ubuntu 16.04
2016-11-16
Giới thiệu về Ứng dụng web tiến bộ (PWA): Service Worker & Manifest
2016-11-10