Python là một ngôn ngữ đẹp để viết mã. Nó có một hệ sinh thái gói tuyệt vời, ít tiếng ồn hơn nhiều so với các ngôn ngữ khác và nó cực kỳ dễ sử dụng.
Python được sử dụng cho nhiều thứ, từ phân tích dữ liệu đến lập trình máy chủ. Và một trường hợp sử dụng thú vị của Python là Web Scraping.
Trong bài viết này, chúng tôi sẽ giới thiệu cách sử dụng Python để quét web. Chúng tôi cũng sẽ làm việc thông qua một hướng dẫn lớp học thực hành hoàn chỉnh khi chúng tôi tiến hành.
Lưu ý: Chúng tôi sẽ cạo một trang web mà tôi lưu trữ, vì vậy chúng ta có thể học cách cạo trên đó một cách an toàn. Nhiều công ty không cho phép cạo trên trang web của họ, vì vậy đây là một cách tốt để tìm hiểu. Chỉ cần đảm bảo kiểm tra trước khi cạo.
Giới thiệu về lớp học Web Scraping

Nếu bạn muốn học viết mã, bạn có thể sử dụng lớp học viết mã miễn phí này bao gồm nhiều phòng thí nghiệm để giúp bạn học quét web. Đây sẽ là một bài tập học tập thực hành trên codedamn, tương tự như cách bạn học trên freeCodeCamp.
Trong lớp học này, bạn sẽ sử dụng trang này để kiểm tra việc quét web: https://codedamn-classrooms.github.io/webscraper-python-codedamn-classroom-website/
Lớp học này bao gồm 7 phòng thí nghiệm và bạn sẽ giải quyết một phòng thí nghiệm trong mỗi phần của bài đăng trên blog này. Chúng tôi sẽ sử dụng Python 3.8 + BeautifulSoup 4 để quét web.
Phần 1: Tải các trang web có ‘yêu cầu’
Đây là liên kết đến phòng thí nghiệm này.
Các requests
mô-đun cho phép bạn gửi các yêu cầu HTTP bằng Python.
Yêu cầu HTTP trả về một Đối tượng phản hồi với tất cả dữ liệu phản hồi (nội dung, mã hóa, trạng thái, v.v.). Một ví dụ về việc lấy HTML của một trang:
import requests
res = requests.get('https://codedamn.com')
print(res.text)
print(res.status_code)
Yêu cầu vượt qua:
- Nhận nội dung của URL sau bằng cách sử dụng
requests
mô-đun: https://codedamn-classrooms.github.io/webscraper-python-codedamn-classroom-website/ - Lưu trữ phản hồi văn bản (như được hiển thị ở trên) trong một biến có tên
txt
- Lưu trữ mã trạng thái (như được hiển thị ở trên) trong một biến có tên
status
- In
txt
vàstatus
sử dụngprint
chức năng
Khi bạn hiểu điều gì đang xảy ra trong đoạn mã trên, việc vượt qua phòng thí nghiệm này khá đơn giản. Đây là giải pháp cho phòng thí nghiệm này:
import requests
# Make a request to https://codedamn-classrooms.github.io/webscraper-python-codedamn-classroom-website/
# Store the result in 'res' variable
res = requests.get(
'https://codedamn-classrooms.github.io/webscraper-python-codedamn-classroom-website/')
txt = res.text
status = res.status_code
print(txt, status)
# print the result
Bây giờ, hãy chuyển sang phần 2, nơi bạn sẽ xây dựng thêm trên mã hiện tại của mình.
Đây là liên kết đến phòng thí nghiệm này.
Trong toàn bộ lớp học này, bạn sẽ sử dụng một thư viện có tên là BeautifulSoup
bằng Python để quét web. Một số tính năng làm cho BeautifulSoup trở thành một giải pháp mạnh mẽ là:
- Nó cung cấp rất nhiều phương thức đơn giản và thành ngữ Pythonic để điều hướng, tìm kiếm và sửa đổi cây DOM. Không mất nhiều mã để viết một ứng dụng
- Beautiful Soup nằm trên các trình phân tích cú pháp Python phổ biến như lxml và html5lib, cho phép bạn thử các chiến lược phân tích cú pháp khác nhau hoặc đánh đổi tốc độ để linh hoạt.
Về cơ bản, BeautifulSoup có thể phân tích cú pháp bất kỳ thứ gì trên web mà bạn cung cấp.
Đây là một ví dụ đơn giản về BeautifulSoup:
from bs4 import BeautifulSoup
page = requests.get("https://codedamn.com")
soup = BeautifulSoup(page.content, 'html.parser')
title = soup.title.text # gets you the text of the <title>(...)</title>
Yêu cầu vượt qua:
- Sử dụng
requests
gói để lấy tiêu đề của URL: https://codedamn-classrooms.github.io/webscraper-python-codedamn-classroom-website/ - Sử dụng BeautifulSoup để lưu trữ tiêu đề của trang này vào một biến có tên
page_title
Nhìn vào ví dụ trên, bạn có thể thấy khi chúng tôi cung cấp page.content
bên trong BeautifulSoup, bạn có thể bắt đầu làm việc với cây DOM đã phân tích cú pháp theo cách rất Pythonic. Giải pháp cho phòng thí nghiệm sẽ là:
import requests
from bs4 import BeautifulSoup
# Make a request to https://codedamn-classrooms.github.io/webscraper-python-codedamn-classroom-website/
page = requests.get(
"https://codedamn-classrooms.github.io/webscraper-python-codedamn-classroom-website/")
soup = BeautifulSoup(page.content, 'html.parser')
# Extract title of page
page_title = soup.title.text
# print the result
print(page_title)
Đây cũng là một bài lab đơn giản mà chúng tôi phải thay đổi URL và in tiêu đề trang. Mã này sẽ vượt qua phòng thí nghiệm.
Phần 3: Cơ thể và đầu Soup-ed
Đây là liên kết đến phòng thí nghiệm này.
Trong phòng thí nghiệm trước, bạn đã thấy cách bạn có thể trích xuất title
từ trang. Việc trích xuất một số phần cũng dễ dàng không kém.
Bạn cũng thấy rằng bạn phải gọi .text
trên những cái này để lấy chuỗi, nhưng bạn có thể in chúng mà không cần gọi .text
và nó sẽ cung cấp cho bạn đánh dấu đầy đủ. Hãy thử chạy ví dụ dưới đây:
import requests
from bs4 import BeautifulSoup
# Make a request
page = requests.get(
"https://codedamn.com")
soup = BeautifulSoup(page.content, 'html.parser')
# Extract title of page
page_title = soup.title.text
# Extract body of page
page_body = soup.body
# Extract head of page
page_head = soup.head
# print the result
print(page_body, page_head)
Chúng ta hãy xem làm thế nào bạn có thể trích xuất body
và head
các phần từ các trang của bạn.
Yêu cầu vượt qua:
- Lặp lại thử nghiệm với URL:
https://codedamn-classrooms.github.io/webscraper-python-codedamn-classroom-website/
- Lưu trữ tiêu đề trang (không gọi .text) của URL trong
page_title
- Lưu trữ nội dung cơ thể (không gọi .text) của URL trong
page_body
- Lưu trữ nội dung đầu (không gọi .text) của URL trong
page_head
Khi bạn cố gắng in page_body
hoặc page_head
bạn sẽ thấy rằng chúng được in dưới dạng strings
. Nhưng trong thực tế, khi bạn print(type page_body)
bạn sẽ thấy nó không phải là một chuỗi nhưng nó hoạt động tốt.
Giải pháp của ví dụ này sẽ đơn giản, dựa trên đoạn mã trên:
import requests
from bs4 import BeautifulSoup
# Make a request
page = requests.get(
"https://codedamn-classrooms.github.io/webscraper-python-codedamn-classroom-website/")
soup = BeautifulSoup(page.content, 'html.parser')
# Extract title of page
page_title = soup.title
# Extract body of page
page_body = soup.body
# Extract head of page
page_head = soup.head
# print the result
print(page_title, page_head)
Phần 4: chọn với BeautifulSoup
Đây là liên kết đến phòng thí nghiệm này.
Bây giờ bạn đã khám phá một số phần của BeautifulSoup, hãy xem cách bạn có thể chọn các thành phần DOM bằng các phương thức BeautifulSoup.
Một khi bạn có soup
biến (như các phòng thí nghiệm trước), bạn có thể làm việc với .select
trên đó là bộ chọn CSS bên trong BeautifulSoup. Tức là bạn có thể tiếp cận cây DOM giống như cách bạn sẽ chọn các phần tử bằng CSS. Hãy xem xét một ví dụ:
import requests
from bs4 import BeautifulSoup
# Make a request
page = requests.get(
"https://codedamn-classrooms.github.io/webscraper-python-codedamn-classroom-website/")
soup = BeautifulSoup(page.content, 'html.parser')
# Extract first <h1>(...)</h1> text
first_h1 = soup.select('h1')[0].text
.select
trả về một danh sách Python của tất cả các phần tử. Đây là lý do tại sao bạn chỉ chọn phần tử đầu tiên ở đây với [0]
mục lục.
Yêu cầu vượt qua:
- Tạo một biến
all_h1_tags
. Đặt nó vào danh sách trống. - Sử dụng
.select
để chọn tất cả các<h1>
các thẻ và lưu trữ văn bản của những h1 đó bên trongall_h1_tags
danh sách. - Tạo một biến
seventh_p_text
và lưu trữ văn bản của ngày 7p
phần tử (chỉ số 6) bên trong.
Giải pháp cho phòng thí nghiệm này là:
import requests
from bs4 import BeautifulSoup
# Make a request
page = requests.get(
"https://codedamn-classrooms.github.io/webscraper-python-codedamn-classroom-website/")
soup = BeautifulSoup(page.content, 'html.parser')
# Create all_h1_tags as empty list
all_h1_tags = []
# Set all_h1_tags to all h1 tags of the soup
for element in soup.select('h1'):
all_h1_tags.append(element.text)
# Create seventh_p_text and set it to 7th p element text of the page
seventh_p_text = soup.select('p')[6].text
print(all_h1_tags, seventh_p_text)
Cứ đi đi.
Phần 5: Top item đang hót hiện nay
Đây là liên kết đến phòng thí nghiệm này.
Hãy tiếp tục và trích xuất các mục hàng đầu được lấy từ URL: https://codedamn-classrooms.github.io/webscraper-python-codedamn-classroom-website/
Nếu bạn mở trang này trong một tab mới, bạn sẽ thấy một số mục hàng đầu. Trong phòng thí nghiệm này, nhiệm vụ của bạn là cạo tên của họ và lưu trữ chúng trong một danh sách có tên là top_items
. Bạn cũng sẽ trích xuất các đánh giá cho các mặt hàng này.
Để vượt qua thử thách này, hãy quan tâm đến những điều sau:
- Sử dụng
.select
để trích xuất các tiêu đề. (Gợi ý: một bộ chọn cho tiêu đề sản phẩm có thể làa.title
) - Sử dụng
.select
để trích xuất nhãn số lượt đánh giá cho các tiêu đề sản phẩm đó. (Gợi ý: một bộ chọn để đánh giá có thể làdiv.ratings
) Lưu ý: đây là nhãn hoàn chỉnh (nghĩa là 2 đánh giá) và không chỉ là một con số. - Tạo một từ điển mới ở định dạng:
info = {
"title": 'Asus AsusPro Adv... '.strip(),
"review": '2 reviews\n\n\n'.strip()
}
- Lưu ý rằng bạn đang sử dụng
strip
để xóa bất kỳ dòng mới/khoảng trắng bổ sung nào bạn có thể có trong đầu ra. Đây là quan trọng để vượt qua phòng thí nghiệm này. - Nối từ điển này vào một danh sách có tên
top_items
- In danh sách này ở cuối
Có khá nhiều nhiệm vụ phải hoàn thành trong thử thách này. Trước tiên chúng ta hãy xem giải pháp và hiểu điều gì đang xảy ra:
import requests
from bs4 import BeautifulSoup
# Make a request
page = requests.get(
"https://codedamn-classrooms.github.io/webscraper-python-codedamn-classroom-website/")
soup = BeautifulSoup(page.content, 'html.parser')
# Create top_items as empty list
top_items = []
# Extract and store in top_items according to instructions on the left
products = soup.select('div.thumbnail')
for elem in products:
title = elem.select('h4 > a.title')[0].text
review_label = elem.select('div.ratings')[0].text
info = {
"title": title.strip(),
"review": review_label.strip()
}
top_items.append(info)
print(top_items)
Lưu ý rằng đây chỉ là một trong những giải pháp. Bạn cũng có thể thử điều này theo một cách khác. Trong giải pháp này:
- Trước hết bạn chọn tất cả các
div.thumbnail
các yếu tố cung cấp cho bạn một danh sách các sản phẩm riêng lẻ - Sau đó, bạn lặp lại chúng
- Bởi vì
select
cho phép bạn tự xâu chuỗi, bạn có thể sử dụng lại chọn để lấy tiêu đề. - Lưu ý rằng vì bạn đang chạy bên trong một vòng lặp cho
div.thumbnail
đã, cách4 > a.title
bộ chọn sẽ chỉ cung cấp cho bạn một kết quả, bên trong danh sách. Bạn chọn phần tử thứ 0 của danh sách đó và trích xuất văn bản. - Cuối cùng, bạn loại bỏ mọi khoảng trắng thừa và thêm nó vào danh sách của mình.
Đơn giản phải không?
Đây là liên kết đến phòng thí nghiệm này.
Đến đây bạn đã biết cách trích xuất văn bản, hay đúng hơn là InternalText của các phần tử. Bây giờ hãy xem cách bạn có thể trích xuất các thuộc tính bằng cách trích xuất các liên kết từ trang.
Đây là một ví dụ về cách trích xuất tất cả thông tin hình ảnh từ trang:
import requests
from bs4 import BeautifulSoup
# Make a request
page = requests.get(
"https://codedamn-classrooms.github.io/webscraper-python-codedamn-classroom-website/")
soup = BeautifulSoup(page.content, 'html.parser')
# Create top_items as empty list
image_data = []
# Extract and store in top_items according to instructions on the left
images = soup.select('img')
for image in images:
src = image.get('src')
alt = image.get('alt')
image_data.append({"src": src, "alt": alt})
print(image_data)
Trong phòng thí nghiệm này, nhiệm vụ của bạn là trích xuất href
thuộc tính của các liên kết với chúng text
cũng. Đảm bảo những điều sau:
- Bạn phải tạo một danh sách có tên
all_links
- Trong danh sách này, lưu trữ tất cả thông tin chính tả liên kết. Nó phải ở định dạng sau:
info = {
"href": "<link here>",
"text": "<link text here>"
}
- Hãy chắc chắn rằng bạn
text
bị tước bỏ mọi khoảng trắng - Hãy chắc chắn rằng bạn kiểm tra nếu bạn
.text
là Không có trước khi bạn gọi.strip()
trên đó. - Lưu trữ tất cả các lệnh này trong
all_links
- In danh sách này ở cuối
Bạn đang trích xuất các giá trị thuộc tính giống như bạn trích xuất các giá trị từ một lệnh, sử dụng get
chức năng. Chúng ta hãy xem giải pháp cho phòng thí nghiệm này:
import requests
from bs4 import BeautifulSoup
# Make a request
page = requests.get(
"https://codedamn-classrooms.github.io/webscraper-python-codedamn-classroom-website/")
soup = BeautifulSoup(page.content, 'html.parser')
# Create top_items as empty list
all_links = []
# Extract and store in top_items according to instructions on the left
links = soup.select('a')
for ahref in links:
text = ahref.text
text = text.strip() if text is not None else ''
href = ahref.get('href')
href = href.strip() if href is not None else ''
all_links.append({"href": href, "text": text})
print(all_links)
Tại đây, bạn giải nén href
thuộc tính giống như bạn đã làm trong trường hợp hình ảnh. Điều duy nhất bạn đang làm cũng là kiểm tra xem nó có Không. Chúng tôi muốn đặt nó thành chuỗi rỗng, nếu không, chúng tôi muốn loại bỏ khoảng trắng.
Phần 7: Tạo CSV từ dữ liệu
Đây là liên kết đến phòng thí nghiệm này.
Cuối cùng, hãy tìm hiểu cách bạn có thể tạo CSV từ một tập hợp dữ liệu. Bạn sẽ tạo một CSV với các tiêu đề sau:
- tên sản phẩm
- Giá bán
- Sự miêu tả
- Đánh giá
- Hình ảnh sản phẩm
Các sản phẩm này nằm trong div.thumbnail
. Bản tóm tắt CSV được đưa ra dưới đây:
import requests
from bs4 import BeautifulSoup
import csv
# Make a request
page = requests.get(
"https://codedamn-classrooms.github.io/webscraper-python-codedamn-classroom-website/")
soup = BeautifulSoup(page.content, 'html.parser')
all_products = []
products = soup.select('div.thumbnail')
for product in products:
# TODO: Work
print("Work on product here")
keys = all_products[0].keys()
with open('products.csv', 'w', newline="") as output_file:
dict_writer = csv.DictWriter(output_file, keys)
dict_writer.writeheader()
dict_writer.writerows(all_products)
Bạn phải trích xuất dữ liệu từ trang web và tạo tệp CSV này cho ba sản phẩm.
Yêu cầu vượt qua:
- Tên sản phẩm là phiên bản rút gọn khoảng trắng của tên mặt hàng (ví dụ – Asus AsusPro Adv..)
- Giá là khoảng trắng được cắt bớt nhưng nhãn giá đầy đủ của sản phẩm (ví dụ – $1101,83)
- Mô tả là phiên bản rút gọn khoảng trắng của mô tả sản phẩm (ví dụ – Asus AsusPro Advanced BU401LA-FA271G Dark Grey, 14″, Core i5-4210U, 4GB, 128GB SSD, Win7 Pro)
- Bài đánh giá là phiên bản được cắt bớt khoảng trắng của sản phẩm (ví dụ – 7 bài đánh giá)
- Hình ảnh sản phẩm là URL (thuộc tính src) của hình ảnh dành cho sản phẩm (ví dụ – /webscraper-python-codedamn-classroom-website/cart2.png)
- Tên của tệp CSV phải là sản phẩm.csv và nên được lưu trữ trong cùng thư mục với của bạn script.py tập tin
Hãy xem giải pháp cho phòng thí nghiệm này:
import requests
from bs4 import BeautifulSoup
import csv
# Make a request
page = requests.get(
"https://codedamn-classrooms.github.io/webscraper-python-codedamn-classroom-website/")
soup = BeautifulSoup(page.content, 'html.parser')
# Create top_items as empty list
all_products = []
# Extract and store in top_items according to instructions on the left
products = soup.select('div.thumbnail')
for product in products:
name = product.select('h4 > a')[0].text.strip()
description = product.select('p.description')[0].text.strip()
price = product.select('h4.price')[0].text.strip()
reviews = product.select('div.ratings')[0].text.strip()
image = product.select('img')[0].get('src')
all_products.append({
"name": name,
"description": description,
"price": price,
"reviews": reviews,
"image": image
})
keys = all_products[0].keys()
with open('products.csv', 'w', newline="") as output_file:
dict_writer = csv.DictWriter(output_file, keys)
dict_writer.writeheader()
dict_writer.writerows(all_products)
Các for
khối là thú vị nhất ở đây. Bạn trích xuất tất cả các yếu tố và thuộc tính từ những gì bạn đã học cho đến nay trong tất cả các phòng thí nghiệm.
Khi bạn chạy mã này, bạn sẽ có một tệp CSV đẹp. Và đó là tất cả những điều cơ bản về tìm kiếm trên web với BeautifulSoup!
Phần kết luận
Tôi hy vọng lớp học tương tác này từ codedamn đã giúp bạn hiểu những kiến thức cơ bản về quét web bằng Python.
Nếu bạn thích lớp học này và blog này, hãy cho tôi biết về nó trên Twitter và Instagram. Rất thích nghe phản hồi!