import json
import os
import re
from datetime import datetime, timezone
from nstdata_ai_crawl import (
Format,
NstDataClient,
ScrapeRequestDto,
)
job_urls = [
"https://careers.example.com/jobs/123",
"https://careers.example.com/jobs/456",
]
def first_heading(markdown: str) -> str | None:
for line in markdown.splitlines():
match = re.match(r"^\s*#{1,3}\s+(.+?)\s*#*\s*$", line)
if match:
return match.group(1).strip()
return None
def labeled_value(markdown: str, labels: list[str]) -> str | None:
"""Ví dụ cho các trang mà phơi bày các trường dưới dạng 'Địa điểm: ...'."""
for raw_line in markdown.splitlines():
line = re.sub(r"[*_]", "", raw_line).strip()
line = re.sub(r"^[-*]\s+", "", line)
for label in labels:
prefix = f"{label}:"
if line.casefold().startswith(prefix.casefold()):
return line[len(prefix):].strip() or None
return None
def parse_job(url: str, markdown: str) -> dict:
return {
"source_url": url,
"observed_at": datetime.now(timezone.utc).isoformat(),
# Xác thực ứng viên này với bố cục trang của trang web mục tiêu.
"title_candidate": first_heading(markdown),
"employer": labeled_value(markdown, ["Công ty", "Nhà tuyển dụng"]),
"location": labeled_value(markdown, ["Địa điểm"]),
"employment_type": labeled_value(
markdown, ["Loại hình việc làm", "Loại công việc"]
),
"salary_text": labeled_value(markdown, ["Lương", "Tiền lương"]),
# Bảo tồn văn bản gốc để việc phân tích sau có thể được sửa chữa.
"description_markdown": markdown,
}
records = []
failures = []
with NstDataClient(os.environ["NSTDATA_API_TOKEN"]) as client:
for url in job_urls:
try:
result = client.submit_scrape_task_sync(
ScrapeRequestDto(
url=url,
formats=[Format.MARKDOWN],
timeout=60_000,
onlyMainContent=True,
)
)
markdown = result.data.get_markdown()
if not markdown or not markdown.strip():
failures.append({"source_url": url, "reason": "empty_markdown"})
continue
records.append(parse_job(url, markdown))
except Exception as exc:
failures.append({
"source_url": url,
"error_type": type(exc).__name__,
})
with open("jobs.jsonl", "w", encoding="utf-8") as output_file:
for record in records:
output_file.write(json.dumps(record, ensure_ascii=False) + "\n")
with open("job_scrape_failures.jsonl", "w", encoding="utf-8") as error_file:
for failure in failures:
error_file.write(json.dumps(failure, ensure_ascii=False) + "\n")
print(f"Đã lưu {len(records)} bản ghi; {len(failures)} trang cần xem xét.")
Bộ phân tích nhãn được thiết kế đơn giản: nó chỉ hoạt động khi một trang trình bày các trường theo các dòng có thể nhận biết như `Location: Boston`. Các trang web nghề nghiệp sử dụng các định dạng khác nhau, vì vậy hãy kiểm tra Markdown và điều chỉnh `parse_job` cho từng nguồn. Đối xử với tiêu đề đầu tiên như một ứng cử viên tiêu đề và xác thực nó; một số trang sử dụng tiêu đề chung như “Careers.” Giữ cho các chi tiết về lương hoặc việc làm bị thiếu rỗng thay vì suy diễn chúng.
### 3. Thu thập một phần nghề nghiệp có giới hạn
Nếu các trang chi tiết việc làm được liên kết từ một phần nghề nghiệp, Nstdata cũng hỗ trợ việc thu thập dữ liệu trang web không đồng bộ. Đặt giới hạn như `maxDepth` và `maxPages` để giữ cho việc khám phá trong phạm vi, sau đó kiểm tra trạng thái nhiệm vụ và lấy kết quả của nó bằng cách sử dụng các API tác vụ được mô tả trong tài liệu. Một lần thu thập toàn bộ trang là hữu ích để phát hiện các trang liên kết; nó không loại bỏ nhu cầu xác thực các URL nào là danh sách việc làm hoặc phân tích cấu trúc trang của từng trang.
### 4. Xác thực và duy trì bộ dữ liệu
Trước khi sử dụng các bản ghi để phân tích, hãy kiểm tra xem mỗi URL có phải là một trang chi tiết việc làm được phép không, xác nhận tiêu đề và vị trí so với nguồn, và xem xét các thất bại và kết quả trống. Gỡ trùng lặp bằng cách sử dụng ID việc làm ổn định từ nguồn khi có; nếu không, sử dụng một URL chuẩn hóa. Lưu `observed_at` để bạn có thể phân biệt khi một danh sách được thu thập từ khi nhà tuyển dụng công bố lần đầu tiên.
Quy trình này tạo ra một bộ nội dung trang việc làm công khai có thể theo dõi. Markdown là bản ghi nguồn; các trường có cấu trúc là một bước phân tích riêng, cụ thể theo nguồn.
## Chi Phí Thu Thập Dữ Liệu Việc Làm Là Bao Nhiêu?
So sánh chi phí toàn bộ của ba phương pháp: sử dụng một API chính thức hoặc nguồn cấp thức ăn được cấp phép, duy trì bộ phân tích của riêng bạn, và sử dụng một API thu thập quản lý cho các nguồn cho phép truy cập tự động.
Một API hoặc nguồn cấp có thể giảm thời gian kỹ thuật, nhưng các điều khoản về phạm vi và tái sử dụng là quan trọng. Một script tự quản lý có chi phí cơ sở hạ tầng cộng với công việc định kỳ cập nhật các chọn lọc, xử lý lại, và xem xét thay đổi nguồn. Một dịch vụ được quản lý có thể giảm hoạt động của trình duyệt và proxy, trong khi ứng dụng của bạn vẫn sở hữu việc lập lịch, làm sạch dữ liệu, lưu trữ, và quản lý nguồn.
Sử dụng chi phí cho mỗi đăng bài hiện tại được chấp nhận thay vì chi phí cho mỗi yêu cầu:
~~~text
chi phí hiệu quả cho mỗi 1.000 đăng bài =
1.000 × (thu thập + cơ sở hạ tầng + kỹ thuật + xem xét + chi phí lưu trữ)
÷ đăng bài hiện tại được chấp nhận
~~~
Để có một ước tính ví dụ, hãy điền vào tỷ lệ kỹ thuật theo giờ của bạn, số lượng nguồn, khối lượng lấy, tỷ lệ ghi chú trùng lặp hoặc hết hạn, và thời gian lưu trữ. Nếu một nguồn thường xuyên thay đổi hoặc tạo ra nhiều trang không sử dụng được, giá yêu cầu rẻ nhất có thể không tạo ra chi phí thấp nhất cho mỗi đăng bài hợp lệ. Đối xử với bất kỳ ước tính nào như một mô hình cho đến khi bạn đo lường một mẫu đại diện.
## Các Considerations Về Pháp Lý, Quyền Riêng Tư, Và Chất Lượng Dữ Liệu
Xem xét các điều khoản nguồn, chính sách API, hướng dẫn robot, quy tắc quyền riêng tư, cấp phép, và mục đích sử dụng dự định của bạn trước khi thu thập. Các thông báo việc làm công cộng không phải là một bộ dữ liệu không giới hạn. Quyền tái sử dụng có thể khác nhau giữa việc xem một trang, giữ bản sao, phân phối các bản ghi phát sinh, và sử dụng dữ liệu cho các quyết định thương mại.
Lưu trữ chỉ các trường cần thiết cho mục đích đã nêu. Giữ một lịch trình lưu giữ và quy trình để loại bỏ các bản ghi cũ hoặc ngoài phạm vi. Giới hạn quyền truy cập vào các mô tả đã thu thập và tránh sử dụng bộ dữ liệu để lập hồ sơ cá nhân ứng viên. Nếu dữ liệu có thể ảnh hưởng đến các quyết định liên quan đến việc làm hoặc một quyết định có tác động lớn khác, hãy nhận được xem xét pháp lý và quyền riêng tư trước khi dựa vào nó.
Chất lượng dữ liệu cần được chăm sóc tương đương. Các tiêu đề công việc khác nhau giữa các nhà tuyển dụng; thông báo lương có thể là hàng năm, hàng giờ, hoặc không có; một vai trò có thể được phản ánh ở nhiều vị trí khác nhau; và ngày của một trang có thể phản ánh một sự chỉnh sửa chứ không phải bản đăng ban đầu. Giữ các giá trị thô, quy tắc chuẩn hóa tài liệu, và báo cáo sự thiếu hụt thay vì lấp đầy nó bằng những phỏng đoán.
## Cách Xây Dựng Một Dòng Dữ Liệu Thị Trường Việc Làm Đáng Tin Cậy
Một quy trình lặp lại thực tiễn là:
1. **Lên lịch thu thập.** Chọn một nhịp dựa trên tần suất cập nhật nguồn và thời gian quyết định. Kiểm tra hàng ngày có thể đủ cho nhiều phân tích thị trường.
2. **Lấy dữ liệu trong phạm vi được phê duyệt.** Sử dụng API chính thức trước tiên ở nơi phù hợp; nếu không, chỉ thu thập các trang công khai được phép.
3. **Chuẩn hóa các trường.** Bảo tồn các chuỗi gốc và thêm các trường vị trí, loại việc làm và bồi thường đã chuẩn hóa.
4. **Gỡ trùng lặp.** Ưu tiên một ID nguồn. Nếu không có sẵn, kết hợp nhà tuyển dụng, tiêu đề, vị trí, và một dấu vân tay mô tả đã chuẩn hóa, sau đó xem xét các trùng lặp không rõ ràng.
5. **Phát hiện các danh sách cũ.** Kiểm tra lại xem một đăng bài còn tồn tại hay không. Đánh dấu nó là đã đóng hoặc không khả dụng với một ngày thay vì xóa ngay lập tức lịch sử.
6. **Lưu trữ lịch sử.** Giữ các quan sát dưới dạng các phiên bản có ngày để các nhà phân tích có thể phân biệt một công việc mới với một danh sách đã chỉnh sửa.
7. **Đo lường phạm vi và chất lượng.** Theo dõi tỷ lệ thành công lấy dữ liệu, tỷ lệ trường hợp hợp lệ, tỷ lệ trùng lặp, tỷ lệ bản ghi cũ, và chi phí cho mỗi bài đăng được chấp nhận.
Một bảng đăng tuyển tối thiểu có thể chứa một ID nội bộ ổn định, ID nguồn, nhà tuyển dụng, tiêu đề, địa điểm, phạm vi lương và tiền tệ, loại hình việc làm, URL nguồn, thời gian lần đầu tiên thấy, thời gian lần cuối thấy, trạng thái, băm nội dung và phiên bản bộ phân tích. Xây dựng xử lý xóa và chỉnh sửa vào thiết kế trước khi chạy theo lịch đầu tiên.
Để biết thêm thông tin về triển khai, xem các hướng dẫn của Nstdata về [các mẫu API URL-to-Markdown](https://www.nstdata.io/blog/url-to-markdown-api), [thu thập dữ liệu tự động](https://www.nstdata.io/blog/automated-data-collection), và [quy trình website-to-JSON](https://www.nstdata.io/blog/website-to-json).
## Kết luận: Xây dựng Tập Dữ Liệu Xung Quanh Bài Đăng
Việc thu thập thông tin việc làm là hữu ích khi một đội cần có một lịch sử nhất quán về các vai trò đã được quảng cáo và có thể xác định các nguồn mà họ được phép sử dụng. Chọn nguồn phù hợp, thu thập các trường tối thiểu hỗ trợ phân tích, bảo tồn thời gian và nguồn gốc, và coi mỗi bản ghi như một quan sát có thể cần xem lại.
<a style="margin: 8px; display: inline-block; text-decoration: none; border-left-width: 0px;" href="https://app.nstdata.io/auth/register?utm_source=official&utm_medium=blog&utm_campaign=/job-scraping-public-job-market-data/">
<div style="font-weight:bold; max-width:400px; padding:12px 40px; background:#646AEE; border-radius:5px; border:2px solid #646AEE; color:#fff; font-size:18px;">
Thử Nstdata Miễn Phí →
</div>
</a>
## Câu Hỏi Thường Gặp
**Q: Thu thập thông tin việc làm là gì?**
Thu thập thông tin việc làm là việc thu thập các trường thông báo việc làm từ các nguồn công cộng hoặc được ủy quyền và tổ chức chúng cho nghiên cứu hoặc phân tích. Một bài đăng chỉ ra một vị trí trống đã được quảng cáo, không phải là một mục tiêu đã hoàn thành.
**Q: Làm thế nào tôi có thể thu thập danh sách việc làm bằng Python?**
Bắt đầu với một API chính thức hoặc nguồn cấp có giấy phép khi có thể. Đối với một nguồn HTML được phép, hãy sử dụng một khách hàng HTTP hoặc công cụ trình duyệt chỉ trong các quy tắc truy cập của nguồn, phân tích các trường cần thiết, và giữ lại URL nguồn và thời gian.
**Q: Thu thập thông tin việc làm có hợp pháp không?**
Điều đó phụ thuộc vào nguồn, khu vực pháp lý, dữ liệu được thu thập, lưu trữ và mục đích sử dụng. Xem xét các điều khoản, nghĩa vụ về quyền riêng tư, cấp phép, và luật pháp áp dụng. Chỉ có sự nhìn thấy công cộng không phải là sự cho phép cho việc tái sử dụng không hạn chế.
**Q: Làm thế nào tôi có thể trích xuất mô tả công việc?**
Sử dụng một nguồn có cấu trúc được ủy quyền nếu có thể. Đối với các trang được phép, trích xuất mô tả trong khi bảo tồn URL gốc và thời gian quan sát, và tránh thu thập thông tin của người nộp đơn hoặc dữ liệu hồ sơ không liên quan.
**Q: Những nguồn nào là tốt cho dữ liệu thị trường việc làm?**
Sử dụng các API thị trường lao động chính thức và các cơ quan thống kê để có danh sách có cấu trúc và xu hướng tổng hợp. Các trang nghề nghiệp của công ty và các nhà cung cấp được cấp phép có thể bổ sung phạm vi khi các điều khoản truy cập và tái sử dụng của họ phù hợp với mục đích nghiên cứu.