Crawl Dữ liệu điểm thi của 2K4 qua kì thi THPTQG 2022

Spid3r

Thành viên
Tham gia
10/3/2023
Bài viết
3
(Vì mình chưa được phép gắn link vào bài viết nên ở mỗi link mình có tách :// --> [:]//, các bạn vui lòng sửa lại trước khi thử)

Ý tưởng
Ý tưởng đầu tiên của mình xuất phát từ năm 2021 (lúc đó mình mới thi THPTQG xong và mong chờ có điểm), thì mình đã lên 1 kế hoạch về việc đi thu thập dữ liệu điểm thi của các bạn và cũng qua idea của 1 người anh về việc "crawl điểm thi các bạn học sinh thi vào 10".

1678442312085.png


Thế nên mình cũng quyết định muốn làm 1 phiên bản cho riêng mình, mình sẽ làm bản thô thôi nhé, k duyệt sang thẳng Excel như anh ấy

Khởi đầu
Lúc này thì mình mới có điểm xong, mình có liên hệ bạn @Phan Thuấn để cùng làm 1 code crawl điểm của các bạn.
Qua 1 thời gian tìm kiếm thì mình thấy trang tra cứu điểm của báo Dân Trí (hiện tại có thể không còn) là có hiện Request URL (đúng thứ mình cần lúc này)

1678442384780.png


Và đường dẫn của request này là https[:]//dantri.com.vn/thpt/1/0/99/27000001/2022/0.2/search-gradle.htm, ở đây ‘27000001’ là SBD mà mình nhập vào
Check trang https[:]//dantri.com.vn/thpt/1/0/99/27000001/2022/0.2/search-gradle.htm thì được

1678442405208.png


Đây chính là thứ mình cần lúc này, nghĩa là nếu thay đổi SBD ở đường dẫn request kia, thì chúng ta sẽ được các thông tin được trả về của từng thí sinh

Hoặc chúng ta check bằng cách sử dụng câu lệnh curl https[:]//dantri.com.vn/thpt/1/0/99/27000001/2022/0.2/search-gradle.htm ta được

1678442421391.png


Vậy việc của chúng ta bây giờ chỉ còn là lọc các thông tin từ đoạn dữ liệu thô này (SBD, điểm toán, điểm văn, …)

Code năm 2021
Sử dụng đơn giản Python (cụ thể là thêm thư viện subprocess)

import subprocess
f = open('diemthiTHPTQG.txt', 'w')
for x in range(27000001,27011078):
url = 'curl https[:]//dantri.com.vn/thpt/1/0/99/'+str(x)+'/2021/0.2/search-gradle.htm'
# Có sự thay đổi trong đường dẫn (2021 - tượng trưng cho năm 2021 và str(x) là để chạy lần lượt từng SBD một)
diem = subprocess.check_output(url)
## Sẽ lấy toàn bộ thông tin từ trang request về
diemthi = str(diem) + '\n'
f.write(diemthi)
f.close()

Sau khi chạy ta sẽ thu về file diemthiTHPTQG.txt (Code này hiện tại không còn dùng được vì toàn bộ data của năm 2021 đã bị đóng, các bạn có thể thử code trên với năm 2022)
1678442655791.png


Sau đó ném sang Excel cộng với 1 vài thao tác cơ bản thì đã có full data điểm của từng thí sinh –> Kết thúc

Code năm 2022
Năm nay dư giả thời gian hơn xíu (1 tuần nữa là thi Cuối Kì) mình lại rảnh rảnh ngồi code Python để cào điểm các em 2k4 (Đã có sự cải tiến code hơn năm ngoái), chơi trội hơn, code mới toanh =)))

import requests
f = open("diemthiTHPTQG.txt", 'a')
for x in range(27000001, 27012001):
scraping_url = "https[:]//dantri.com.vn/thpt/1/0/99/" + str(x) + "/2022/0.2/search-gradle.htm"
payload = {}
headers = {}
response = requests.request(
"GET", scraping_url, headers=headers, data=payload)
info = response.json()['student']
diem = "SBD {} Toan {} Van {} Ngoaingu {} Vatly {} Hoahoc {} Sinhhoc {} KHTN {} Lichsu {} Dialy {} GDCD {} KHXH {}".format(
info['sbd'], info['toan'], info['van'], info['ngoaiNgu'], info['vatLy'], info['hoaHoc'], info['sinhHoc'], info['diemTBTuNhien'], info['lichSu'], info['diaLy'], info['gdcd'], info['diemTBXaHoi'])
diemthi = str(diem) +'\n'
f.write(diemthi)
f.close

Đối với các tỉnh có mã đầu 0 ví dụ Hà Nội là 01 chẳng hạn, thì thay vì các bạn viết cái scraping_url là
"https[:]//dantri.com.vn/thpt/1/0/99/" + str(x) + "/2022/0.2/search-gradle.htm"
Thì các bạn viết thành
"https[:]//dantri.com.vn/thpt/1/0/99/0" + str(x) + "/2022/0.2/search-gradle.htm"
và thay vòng lặp x bắt đầu từ 1000001 (tương ứng với 01000001) tới số nào đó (nhưng lúc này chỉ có 7 chữ số thôi nhém đã bỏ số 0 ở đầu)
Cũng cùng ý tưởng như năm ngoái, nhưng năm nay với cái dữ liệu thô mình cào về được, thì mình đã lọc luôn (năm nay chỉ chơi thư viện request mạnh hẳn)

việc mình dùng info = response.json()['student'] để lọc các dữ liệu từ trường student (chứa các thông tin quan trọng nhất)
và info[‘sbd’] rồi info[’toan’] là mình lấy từ việc "student":{"sbd":"27000001","toan":"7.60", ...
Và sau khi chạy file thì mình k thể thấy được việc nó thu thập dữ liệu trong terminal (mà chỉ thấy nó điền dần dần vào trong file) nên lúc đầu mình tưởng lỗi, mình quay ra thử print luôn vào terminal thì thấy tốc độ nó crawl rất nhanh (1s phải tầm 12 - 15 dòng) suy ra 11k bạn của Ninh Bình thì mất tầm 666 - 833 giây xấp xỉ 10 - 14 phút là cào xong 1 tỉnh (tương tự với việc thay mã tỉnh sẽ cào được các tỉnh khác).
Để thuận tiện cho việc chuyển sang Excel thì mình xoá hết chú thích của các thông tin đi

diem = "{} {} {} {} {} {} {} {} {} {} {} {}".format(
info['sbd'], info['toan'], info['van'], info['ngoaiNgu'], info['vatLy'], info['hoaHoc'], info['sinhHoc'], info['diemTBTuNhien'], info['lichSu'], info['diaLy'], info['gdcd'], info['diemTBXaHoi'])

Dữ liệu cào được belike:

1678442489659.png


Sau khi cào xong ném sang Python và lọc bằng phương pháp text to column ta được file điểm hoàn chỉnh:

1678442698444.png


Vậy là đã xong việc cào điểm các bạn 2k4 từ kì thi THPTQG

Kết thúc
Từ lần này, mình rút ra vài điều cho các bạn muốn crawl dữ liệu 1 web nào đó:
Thứ nhất, các bạn cần tìm hiểu xem web nào có hiện request URL (sẽ dễ làm hơn với các bạn newbie) thì sẽ dễ hơn, còn nếu không có thì mình sẽ hướng dẫn trong bài lần sau
Thứ hai, thư viện của Python rất mạnh, các bạn có thể dựa vào đó để code lấy data 1 cách ngon lành
Thứ ba, cào điểm như này không ảnh hưởng nhiều đến web cho lắm, cũng như không vi phạm pháp luật, đừng bạn nào rủa mình đi tù nữa =)))
Thứ tư, mình có làm video hướng dẫn trên youtube nhé

1678442762624.png
 
×
Quay lại
Top