Các bài tập thực tế về thu thập dữ liệu web với nhiều kỹ thuật khác nhau
Bài tập 1: Xử lý chuyển hướng và tính toán giá trị trung bình
Sử dụng trình duyệt tự động để truy cập trang đích và tính toán giá trị trung bình từ bảng dữ liệu.
from selenium import webdriver
from selenium.webdriver.common.by import By
trinh_dieu_huong = webdriver.Chrome()
trinh_dieu_huong.get("https://spiderbuf.cn/web-scraping-practice/scraper-practice-c01")
trinh_dieu_huong.find_element(By.XPATH, '//a[contains(@href, "mnist")]').click()
danh_sach_hang = trinh_dieu_huong.find_elements(By.CSS_SELECTOR, 'table.table tbody tr')
tong_pix = 0
for hang in danh_sach_hang:
pixel = int(hang.find_element(By.XPATH, './/td[2]').text)
tong_pix += pixel
print(f"Trung bình cột Pix1: {tong_pix/len(danh_sach_hang):.2f}")
trinh_dieu_huong.quit()
Bài tập 2: Tương tác với thanh trượt
Giải quyết cơ chế xác thực bằng cách mô phỏng thao tác kéo thanh trượt và xử lý dữ liệu bảng.
from selenium import webdriver
from selenium.webdriver import ActionChains
from selenium.webdriver.common.by import By
trinh_dieu_huong = webdriver.Chrome()
trinh_dieu_huong.get("https://spiderbuf.cn/web-scraping-practice/scraper-practice-c02")
thanh_truot = trinh_dieu_huong.find_element(By.ID, "slider")
kich_thuoc_keo = 250
hanh_dong = ActionChains(trinh_dieu_huong)
hanh_dong.click_and_hold(thanh_truot).pause(0.2)
hanh_dong.move_by_offset(kich_thuoc_keo - 5, 0).pause(0.5)
hanh_dong.move_by_offset(5, 0).release().perform()
bang_gia = trinh_dieu_huong.find_elements(By.XPATH, '//table[@id="flightTable"]/tbody/tr')
tong_gia = sum(int(hang.find_element(By.XPATH, './/td[3]').text) for hang in bang_gia)
print(f"Giá vé trung bình: {tong_gia/len(bang_gia):.2f}")
Bài tập 3: Giải mã yêu cầu API bằng JavaScript
Xử lý yêu cầu POST với tham số mã hóa bằng cách thực thi mã JavaScript trong môi trường Python.
import execjs
import requests
with open('giai_ma_c03.js', 'r') as f:
bo_giai_ma = execjs.compile(f.read())
tong_sepal = 0
for trang in range(1, 6):
tham_so = bo_giai_ma.call('taoThamSo', trang)
phản_hồi = requests.post(
"https://spiderbuf.cn/web-scraping-practice/scraper-practice-c03",
json=tham_so,
headers={'User-Agent': 'Mozilla/5.0'}
)
for muc in phản_hồi.json():
tong_sepal += float(muc['sepal_width'])
print(f"Tổng cột sepal_width: {tong_sepal:.2f}")
Bài tập 4: Kích hoạt sự kiện JavaScript
Vượt qua xác thực bằng cách gọi trực tiếp hàm JavaScript thay vì tương tác giao diện.
from selenium import webdriver
from selenium.webdriver.common.by import By
trinh_dieu_huong = webdriver.Chrome()
trinh_dieu_huong.get("https://spiderbuf.cn/web-scraping-practice/scraper-practice-c04")
trinh_dieu_huong.execute_script("xacNhanCaptcha()")
cac_bai_dang = trinh_dieu_huong.find_elements(By.CSS_SELECTOR, '#posts > div')
tong_doc = 0
tong_binh_luan = 0
for bai in cac_bai_dang:
luot_doc = int(bai.find_element(By.CSS_SELECTOR, 'span:first-child').text.split()[1])
binh_luan = int(bai.find_element(By.CSS_SELECTOR, 'span span span').text.replace(',', ''))
tong_doc += luot_doc
tong_binh_luan += binh_luan
print(f"Trung bình lượt đọc và bình luận: {(tong_doc + tong_binh_luan)/len(cac_bai_dang):.2f}")
Bài tập 5: Xử lý thanh trượt với khoảng cách động
Tinh chỉnh thao tác kéo thanh trượt dựa trên phân tích khoảng cách thực tế.
from selenium.webdriver import ActionChains
trinh_dieu_huong.get("https://spiderbuf.cn/web-scraping-practice/scraper-practice-c05")
thanh_truot = trinh_dieu_huong.find_element(By.ID, "slider")
hanh_dong = ActionChains(trinh_dieu_huong)
hanh_dong.click_and_hold(thanh_truot)
hanh_dong.move_by_offset(210, 0).pause(0.3)
hanh_dong.move_by_offset(6, 0).release().perform()
# Tính toán giá vé tương tự Bài tập 2
Bài tập 6: Kết hợp Selenium và giải mã API
Xử lý dữ liệu ban đầu từ DOM và yêu cầu API mã hóa.
import execjs
# Lấy dữ liệu ban đầu từ DOM
cac_muc = trinh_dieu_huong.find_elements(By.CSS_SELECTOR, '#items > div')
tong_diem = sum(float(muc.find_element(By.CSS_SELECTOR, 'p span:last-child').text) for muc in cac_muc)
# Giải mã API
with open('giai_ma_c06.js') as f:
bo_giai_ma = execjs.compile(f.read())
tham_so = bo_giai_ma.call('taoThamSo')
phản_hồi = requests.post(
"https://spiderbuf.cn/web-scraping-practice/scraper-practice-c06",
json=tham_so
)
for muc in phản_hồi.json():
tong_diem += float(muc['rating'])
print(f"Tổng điểm đánh giá: {tong_diem:.2f}")
Bài tập 7: Phân tích mã hóa tham số phức tạp
Xử lý yêu cầu với nhiều tham số mã hóa và tính toán giá trị CPC.
import execjs
with open('giai_ma_c07.js') as f:
bo_giai_ma = execjs.compile(f.read())
tham_so = bo_giai_ma.call('sinhThamSo')
phản_hồi = requests.post(
"https://spiderbuf.cn/web-scraping-practice/scraper-practice-c07",
json=tham_so,
cookies={'_asd2sdf99': tham_so['ma_bam']}
)
tong_cpc = 0
for muc in phản_hồi.json():
cpc = (int(muc['cpc_usd']) ^ int(muc['monthly_search_volume'])) / 100
tong_cpc += cpc
print(f"Trung bình CPC: {tong_cpc/len(phản_hồi.json()):.2f}")
Bài tập 8: Giải mã phản hồi API
Xử lý phản hồi mã hóa bằng kỹ thuật giải mã ngược.
tham_so = bo_giai_ma.call('taoYeuCau')
phản_hồi = requests.get(
f"https://spiderbuf.cn/web-scraping-practice/scraper-practice-c08/api?t={tham_so['thoi_gian']}",
params={'s': tham_so['muoi'], 'sig': tham_so['ky_hieu']}
)
du_lieu_ma_hoa = phản_hồi.json()['d']
du_lieu_goc = bo_giai_ma.call('giaiMa', du_lieu_ma_hoa, tham_so['chung_thuc'])
tong_gia = sum(muc['price'] for muc in du_lieu_goc)
print(f"Trung bình giá: {tong_gia/len(du_lieu_goc):.2f}")
Bài tập 9: Xử lý token xác thực động
Quản lý cookie và tham số thời gian thực để truy cập API.
from DrissionPage import SessionPage
trang = SessionPage()
trang.get("https://spiderbuf.cn/web-scraping-practice/scraper-practice-c09")
token = trang.cookies().get('_token_c09')
tham_so = bo_giai_ma.call('maHoa', token)
phản_hồi = requests.post(
"https://spiderbuf.cn/web-scraping-practice/scraper-practice-c09",
json={'tt': tham_so['thoi_gian'], 's': tham_so['ma']},
headers={'X-Client-Id': '967138...'}
)
# Tính toán CPC tương tự Bài tập 7
Bài tập 10: Phân tích dữ liệu bảng
Sử dụng thư viện xử lý dữ liệu để tổng hợp thông tin từ bảng HTML.
from DrissionPage import Chromium
import pandas as pd
trinh_dieu_huong = Chromium()
trang = trinh_dieu_huong.new_tab()
trang.get("https://spiderbuf.cn/web-scraping-practice/scraper-practice-js-reverse-c10")
bang = trang.ele('table').ele('tbody')
danh_sach = [[td.text for td in hang.eles('td')] for hang in bang.eles('tr')]
khung_du_lieu = pd.DataFrame(danh_sach, columns=['a','b','c','d','e','f'])
khung_du_lieu['b'] = pd.to_numeric(khung_du_lieu['b'])
tong_nhom = khung_du_lieu.groupby('f')['b'].sum()[['Ahrefs', 'SEMrush']].sum()
print(f"Tổng nhóm Ahrefs và SEMrush: {tong_nhom:.2f}")