
Xin chào mọi người,
Chuyện là ngày hôm nay đi làm về, thì mình nhận được tin nhắn của một người bạn, nhờ mình giúp scrape data từ một website tên là Wind Energy Hamburg.

Cụ thể là data 1400 records về các công ty sẽ tham dự một buổi triễn lãm, và các thông tin cần scrape bao gồm:

Mình ngó một vòng qua trang web thì đại loại web sẽ display cho user 1 list các công ty trong sự kiện, có thêm thanh search, và các thể loại filter để mình có thể query. Mỗi lần display sẽ tầm 30 records, và nếu muốn xem thêm thì phải kéo đến cuối trang và ấn “Load more”.

Khi tiếp cận với một bài toán data scraping từ website đối với một dân không chuyên data như mình thì mình sẽ luôn nghĩ đến 2 cách đầu tiên đó là:
Cách đầu tiên thì mình nghĩ là có vẻ không khả thi lắm, vì mỗi lần load 30 records, mà load đến khi display đủ 1400 records, thì chắc đến Tết Congo. Không loại trừ khả năng load đến 1 đoạn mà program hay browser nó crash thì không biết đâu mà lần 🥴.
Vậy nên mình bắt đầu nghĩ sang hướng của cách thứ 2, có thể họ sẽ public API, vì dù sao đây cũng là 1 web để tra cứu thông tin. Ngoài ra bạn mình cũng có nhắc đến là thử xài 1 cái tool nào trên mạng mà lấy được có 30 cái. Đến đây thì mình nghĩ là có khả năng sẽ được, nên bắt tay vào nghiên cứu.
Đầu tiên mình vào link website bình thường, mở dev tool thần thánh (F12) lên, và vào mục Network

Nếu mà ở đây không hiện gì, thì mọi người có thể load lại trang (nhớ ấn giữ shift rồi ấn reload để web không bị dính caching nhé). Sau đó filter mục Fetch/XHR để quan sát những file json mà server gửi ngược lại cho mình.

Giờ thì ngồi mò từng file thôi 🤣. Mình sẽ xem phần Preview hoặc Response của từng file, đến file cuối cùng thì tada!. Từ 0 đến 29 là 30 records, xem vài cái đầu thì match, chắc chắn là đúng đúng rồi đây.

Oke xác định được data nằm ở đâu rồi thì lấy API gọi trực tiếp thử xem có được không. Mình vào mục Headers để lấy Request URL nhé.

Quan sát thì thấy ở cuối URL có vẻ là có query selector = 30, nên mình đổi sang 1 luôn rồi gọi thử thì nhận được luôn.

Đến đây thì gần như là xong nhiệm vụ rồi kkk 🥳. Mình thử set luôn query selector limit = 1400 ở request URL thì không trả lại gì, có vẻ là bị timeout. Sau một hồi thử đi thử lại thì limit = 200, vẫn trả data lại mặc dù load khá lâu, tầm 20s.
Giờ thì việc tiếp theo là làm sao lấy được 1400 records về. Sau một hồi suy nghĩ thì mình lại vào dev tool quan sát. Mình ấn load more và quan sát xem 2 URL này khác gì nhau.

Đặc biệt là trong lúc ngắm nghía cái URL thì mình thấy được 1 cái query selector page , và ấn load more thì value chuyển từ 0 thành 1 . Rồi, mình gọi 6 lần API limit =200, và page từ 0-6, vị chị là 1400 records. Mình lưu thành 7 files json, rồi giờ đến việc lưu data vào file excel.
Nhìn vào structure của fil json thì mình sẽ cần lấy các field sau:
tương đương với:

Giờ thì mình nhờ ChatGPT viết giúp 1 cái python program để parse các field này ra 1 file excel là coi như xong.
import json
import pandas as pd
import os
def parse_multiple_json_to_excel(json_files, output_excel_file):
# Prepare a list to store data from all files
all_items = []
# Loop through each JSON file
for json_file in json_files:
# Load the JSON data from the file
with open(json_file, 'r') as file:
data = json.load(file)
# Extract the relevant fields
for item in data['items']:
item_dict = {
'Title': item.get('title')
}
# Process object information (stand and classification)
objects = item.get('object', [])
if objects:
stands = objects[0].get('stand', [])
if stands:
stand_info = stands[0]
item_dict['ExpoHall'] = stand_info.get('expoHall')
item_dict['StandNo'] = stand_info.get('standNo')
classifications = objects[0].get('classification', [])
if classifications:
# If there are multiple classifications, join the titles with a comma
item_dict['ClassificationTitle'] = ", ".join([c.get('classificationTitle', '') for c in classifications])
# Append this item's data to the list
all_items.append(item_dict)
# Convert the combined list to a DataFrame
df = pd.DataFrame(all_items)
# Write the DataFrame to an Excel file
df.to_excel(output_excel_file, index=False)
print(f"Data successfully written to {output_excel_file}")
# Usage
folder_path = 'path_to_your_json_files'
json_files = [os.path.join(folder_path, f) for f in os.listdir(folder_path) if f.endswith('.json')]
output_excel_file = 'combined_output.xlsx'
parse_multiple_json_to_excel(json_files, output_excel_file)
Kết quả là một file excel 1400 dòng như yêu cầu 🤩

Đến đây là kết thúc task, mình gửi lại file excel chứa data. Đối với một người không có kinh nghiệm làm data và chưa bao giờ scrape data, thì cũng coi như là học được một thứ mới hay ho. Nếu mình có nói sai kiến thức hoặc thuật ngữ thì xin mọi người thông cảm và liên hệ để mình có thể chỉnh sửa kịp thời nhé. Cảm ơn mọi người đã đọc!
An Nguyễn




