CodeGym /Khóa học Java /Python SELF VI /Thu thập dữ liệu với liên kết "Tiếp theo"

Thu thập dữ liệu với liên kết "Tiếp theo"

Python SELF VI
Mức độ , Bài học
Có sẵn

1. Giới thiệu về phân trang

Ai bảo rằng dữ liệu bạn cần sẽ nằm trên một trang duy nhất? Rất thường xuyên bạn phải kéo chúng từ rất nhiều trang, hoặc thậm chí dữ liệu bị rải rác khắp nơi trên trang web. Vì vậy, một trong những thử thách đầu tiên bạn sẽ gặp phải là việc chia dữ liệu thành các trang (pages). Và công việc thú vị để thu thập chúng được gọi là pagination (phân trang).

Đúng vậy, phân trang không chỉ là lúc bạn chờ đợi chuyển sang trang kết quả tiếp theo của Google, mà còn là khi web-scraper tự hỏi: "Làm sao để tự động hóa điều này, thay vì làm thủ công?"

Phân trang là một cách tổ chức dữ liệu trên website để tránh các trang dài lê thê với nội dung. Thay vào đó, các website chia nhỏ dữ liệu thành từng trang và thêm các liên kết như "Tiếp theo" hoặc "Dẫn tiếp" để chuyển đổi từ trang này sang trang khác. Đây là một khái niệm quan trọng vì bạn, với tư cách là một web-scraper, sẽ không muốn nói với sếp của mình rằng bạn không thu thập được gì chỉ vì dữ liệu bị giấu ở "trang thứ 5".

2. Các vấn đề khi thu thập dữ liệu từ nhiều trang

Vấn đề đầu tiên bạn có thể gặp — đó là sự thiếu rõ ràng và dự đoán trong URL. Một số trang web không thay đổi URL một cách rõ ràng khi bạn di chuyển giữa các trang, điều này làm cho việc tự động hóa trở nên khá khó khăn. Ví dụ, thay vì page=1, page=2, bạn có thể gặp phải x=abc, x=def mà không có bất kỳ quy luật nào rõ ràng.

Vấn đề thứ hai — bảo vệ chống bot. Một số trang web tích cực theo dõi số lượng yêu cầu từ một địa chỉ IP. Nếu họ thấy bạn làm quá nhiều, bạn có thể bị chặn tạm thời (hoặc vĩnh viễn).

Nhưng đừng lo, chúng ta sẽ học cách vượt qua những khó khăn này như những scraper chuyên nghiệp.

3. Vượt qua phân trang

Các kỹ thuật và chiến lược

  1. Phân tích cấu trúc URL: Thông thường, các trang sử dụng tham số trong URL để chỉ định số trang, ví dụ như ?page=2. Nếu bạn phát hiện điều này, chúc mừng, bạn đã tìm thấy khuôn mẫu vàng để vượt qua phân trang!
  2. Tìm liên kết "Tiếp theo": Đôi khi URL không thể dự đoán được. Trong những trường hợp như vậy, bạn cần tìm các liên kết "Tiếp theo" hoặc "Dẫn tiếp" trên trang và theo dõi chúng.
  3. Sử dụng AJAX requests: Một số trang web tải dữ liệu bằng AJAX mà không cần tải lại trang. Trong trường hợp này, bạn cần chặn các yêu cầu này và tái tạo chúng.

Chúng ta cùng thực hành nhé!

Ví dụ về script để vượt qua phân trang và thu thập dữ liệu

Chúng ta hãy xem một ví dụ về script:

Python

import requests
from bs4 import BeautifulSoup

# Hàm để lấy dữ liệu từ một trang
def get_data_from_page(url):
    response = requests.get(url)
    if response.status_code == 200:
        soup = BeautifulSoup(response.text, 'html.parser')
        # Ở đây bạn trích xuất dữ liệu từ soup — ví dụ
        data = soup.find_all('div', class_='data-class')
        for item in data:
            print(item.text)  # In hoặc lưu dữ liệu
    else:
        print(f"Không thể lấy trang: {url}")

# Logic chính để đi qua các trang
def scrape_all_pages(start_url):
    current_url = start_url
    while current_url:
        get_data_from_page(current_url)
        soup = BeautifulSoup(requests.get(current_url).text, 'html.parser')
        # Thử tìm liên kết "Tiếp theo"
        next_button = soup.find('a', text='Tiếp theo')
        if next_button:
            current_url = next_button['href']
        else:
            current_url = None

# Bắt đầu scraping từ trang đầu tiên
start_url = 'http://example.com/page=1'
scrape_all_pages(start_url)

Đây là một ví dụ cơ bản để minh họa nguyên tắc làm việc với phân trang. Bạn sẽ cần phải điều chỉnh nó dựa trên cấu trúc của trang web mà bạn đang làm việc.

Quản lý session và sử dụng user-agent

Khi bạn gửi nhiều yêu cầu đến một trang web, việc sử dụng session và thay đổi user-agent là hữu ích để giảm nguy cơ bị chặn.

Python

headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.3'}

session = requests.Session()
session.headers.update(headers)

response = session.get('http://example.com')

Cấu trúc này cho phép giả lập trình duyệt một cách đáng tin cậy hơn là chỉ gửi các yêu cầu với headers trống.

4. Thực hành

Bây giờ, khi chúng ta đã biết những điều cơ bản, hãy cùng làm nhiệm vụ phức tạp hơn một chút. Xem xét trường hợp liên kết trang chứa các tham số không thể đoán trước và chúng ta cần sử dụng AJAX để thu thập dữ liệu.

Thực thi bằng việc sử dụng AJAX

Đôi khi dữ liệu không được tải trên trang chính mà được tải qua AJAX. Nếu bạn phát hiện rằng website hoạt động như vậy, hãy sử dụng công cụ debug network trong trình duyệt để xác định những yêu cầu nào đang được gửi ở chế độ nền. Sau đó, tái tạo chúng bằng Python.

Python

# Ví dụ gọi AJAX
ajax_url = 'http://example.com/ajax_endpoint'

params = {
'some_param': 'value',  # Tham số, nếu cần thiết cho request
'page': 1
}

while True:
response = session.get(ajax_url, params=params)
data = response.json()
if not data['has_more']:
break
# Xử lý dữ liệu
for item in data['items']:
print(item)
params['page'] += 1  # Chuyển sang trang tiếp theo

Phương pháp này hữu ích trong trường hợp sau khi phân tích chi tiết về yêu cầu và phản hồi bạn hiểu cách dữ liệu được tải trong trình duyệt.

Bài giảng hôm nay đã đưa chúng ta vào thế giới thú vị và thường đầy thách thức của phân trang. Kỹ năng này sẽ giúp bạn tự tin và hiệu quả trong việc thu thập dữ liệu từ các trang web mà không bỏ sót bất kỳ trang nào. Cuối cùng, cũng như trong cuộc sống, trong web-scraping, tính phương pháp và sự kiên nhẫn là quan trọng, bởi ai biết được những kho báu bí ẩn nào nằm trên trang thứ hai mươi!

Bình luận
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION