Xem nhanh
Bài toán
Các sếp muốn ước tính số lượng đơn hàng của đối thủ như Giao Hàng Nhanh. Nhận thấy tiềm năng khai thác public API của Giao Hàng Nhanh, tôi đã tiến hành cào dữ liệu và cung cấp những insight giá trị cho các sếp.
Sau đó tôi tiếp tục mở rộng thêm việc khai thác dữ liệu đối với Best Express và LEX, phát triển module chuẩn hóa hơn, xây dựng data pipeline khai thác dữ liệu liên tục và lữu trữ vào BigQuery để phân tích về tuyến và năng lực vận hành của các đối thủ.
Khó khăn và giải pháp
Tìm ra quy tắc của mã đơn hàng
Việc này tốn khá nhiều thời gian, mỗi đối thủ sẽ có một hoặc nhiều quy tắc đặt mã đơn hàng khác nhau.
Tôi sẽ ví dụ về một quy tắc của một đối thủ. Bình thường thì “1 chục” là 10 đơn vị, ở Bến Tre thì “1 chục dừa” là 12 đơn vị. Theo cách hiểu đó, đối thủ này tạo ra quy tắc “1 chục” là 26 đơn vị.
Sau đó, mỗi đơn vị sẽ được thể hiện bằng một ký tự là chữ hoặc số (ví dụ: 0 là Q, 1 là L, 2 là F, … cho đến 26). Từ đó bộ số này có thể tăng dần như số bình thường.
Vượt qua rate limit, tường lửa Cloudflare và captcha
Giống như cuộc chiến thầm lặng giữa tôi và đội dev của đối thủ. Mỗi lần họ nâng cấp bảo mật là mỗi lần tôi tìm cách giải bảo mật.
Rate limit
- Cách đơn giản là thử nghiệm nhiều khoảng thời gian sleep khác nhau cho đến khi không còn bị rate limit.
- Nâng cấp hơn thì tìm ra số lượng cho phép trong một khoảng thời gian, ví dụ như 45 đơn / 1 phút. Sau đó chỉnh lại khoản thời gian sleep để lấy được tối đa có thể.
Tường lửa Cloudflare
Tôi tìm ra thư viện cloudscraper giúp request không còn bị chặn bởi Cloudflare.
Captcha
Chủ yếu nhờ lỗ hỏng bảo mật của họ, có các trường hợp sau:
- Response phản hồi thất bại nhưng kèm đáp án đúng → Tôi lấy đáp án đúng để trả lời lại lần nữa thì được qua.
- Nhận thấy captcha là một dịch vụ của bên thứ 3, tôi nghĩ rằng họ phải có phương án dự phòng khi bên thứ 3 này sập, vì vậy tôi tắt JS captcha và thấy rằng website vẫn cho phép tìm đơn hàng. Tôi nhận ra header của request sau khi tắt JS captcha sẽ khác với lúc bình thường. Tôi sử dụng header đó để request và bypass captcha.
Xác định đơn đầu tiên của một ngày cụ thể
Logic này sẽ giúp tôi:
- Tạo ra danh sách đơn cần cào cho một khoảng thời gian.
- Tính nhanh số lượng đơn hàng của một khoảng thời gian khá chính xác.
Cách thực hiện chính là “kiểm tra với bước nhảy giảm dần”. Ví dụ: [100000, 10000, 1000, 100, 10, 1]
- Lấy một mã đơn hàng của quá khứ (khoảng 1 tháng trước), đổi mã đơn hàng thành số đơn hàng, dùng số đơn hàng + bước nhảy để dò đơn.
- Với mỗi bước nhảy, tôi sẽ kiểm tra xem dữ liệu để xem ngày tạo đơn đã vượt qua ngày cần tìm hay chưa.
- Nếu chưa thì tiếp tục với bước nhảy hiện tại.
- Nếu đã vượt thì lùi lại, hạ bước nhảy xuống mức thấp hơn rồi tiếp tục.
- Cho đến khi chỉ bước nhảy chỉ là 1 và ngày tạo đơn vừa ≥ ngày đang tìm → Đó chính là đơn đầu tiên.
Trường hợp lỗi giữa chừng hoặc máy chủ bị mất điện
Tôi setup một Linux server bằng PC trên công ty, vì vậy việc mất điện hoặc mất wifi trong lúc đang khai thác dữ liệu là khó tránh khỏi. Lúc đó, script sẽ bị hỏng.
- Mất điện: Tôi cài đặt PC tự động mở nguồn khi có điện.
- Mất wifi: Tôi viết một hàm kiểm tra kết nối và chờ thử lại, mỗi khi mất wifi script sẽ tự gọi hàm này và tiếp tục việc cào khi có tín hiệu mạng trở lại.
- Script bị dừng: Tôi thiết lập cron tự động chạy lại các script ngay khi PC vừa khởi động xong. Đồng thời cào tiếp tục từ vị trí bị dừng chứ không phải cài lại từ đầu. Tất cả các function đều có decorator retry nhiều lần giản cách trước khi raise lỗi.
Kết quả
- Module có thể nhanh chóng cho biết số lượng trong tháng hoặc một khoản thời gian bất kỳ mà không cần phải cào hết toàn bộ đơn. Dựa vào logic tìm đơn đầu tiên của một ngày cụ thể.
- Cung cấp insight hữu ích về số lượng đơn hàng, phân bổ khu vực, tốc độ giao hàng của các đối thủ và xu hướng chung của ngành cho các sếp. Từ đó các sếp hoạch định chiến lược, điều chỉnh KPI với bộ phận vận hành.
Tôi tự hào về dự án này, nhưng tôi không chắc trong tương lai tôi sẽ làm lại được hay không vì quy tắc mã đơn hàng và các lớp bảo mật không phải lúc nào cũng giải được. Cũng như câu “Thời thế tạo anh hùng”.
