Cách thu thập dữ liệu trang web một cách có trách nhiệm và giảm thiểu các khối có thể tránh được
TL;DR
Việc giảm thiểu các khối không cần thiết bắt đầu bằng cách cấp quyền truy cập được chấp thuận, phạm vi rõ ràng, xác định trung thực và giảm lượng yêu cầu không cần thiết.
Một sự cho phép robot không phải là một giấy phép nội dung, và một nhà cung cấp được quản lý không ghi đè quyết định truy cập của một trang web.
Xem các lỗi ủy quyền như là các điều kiện dừng; xử lý giới hạn tần suất với hướng dẫn thời gian của máy chủ và ngân sách thử lại đã giới hạn.
Phối hợp tốc độ giữa các công nhân ở mức nguồn gốc, không chỉ thông qua những khoảng dừng trong các nhiệm vụ riêng lẻ.
Ví dụ có thể thực thi bên dưới được giới hạn cố ý ở example.com và xác thực chính sách, tốc độ, nội dung và trạng thái thất bại thay vì trình diễn sự lẩn tránh.
Việc thu thập có trách nhiệm giảm tải không cần thiết, không phải mọi sự từ chối có thể có
Việc thu thập có trách nhiệm có thể giảm thiểu các khối có thể tránh được do các lần thử lại quá nhiều, mở rộng phạm vi vô tình, yêu cầu trùng lặp, và công việc thu thập bị sai định dạng. Nó không thể đảm bảo truy cập vào một nguồn mà từ chối thu thập tự động. Mục tiêu của “thu thập mà không bị chặn” nên là một quy trình thu thập được cho phép và có thể đo lường—không phải là buộc một yêu cầu bị từ chối phải thành công.
Một công cụ thu thập có thể lãng phí lưu lượng trước khi nó gặp từ chối. Các liên kết phân trang không chuẩn hóa có thể tạo ra các nhiệm vụ trùng lặp; mỗi công nhân có thể thử lại cùng một tài nguyên không khả dụng; việc trình bày trên trình duyệt có thể tải lại các tài sản lớn cho các trang mà không bao giờ cần một trình duyệt. Những vấn đề này cần được khắc phục độc lập với bất kỳ lựa chọn nhà cung cấp hoặc proxy nào.
Nstdata Crawl có thể di chuyển việc lấy trang và khám phá có giới hạn vào một dịch vụ được quản lý. Ứng dụng vẫn phải thi hành các máy chủ được chấp thuận, ngân sách thu thập, và kết quả cuối cùng. Hướng dẫn scraper-versus-crawler giải thích tại sao việc khám phá và trích xuất dữ liệu cần các hợp đồng riêng biệt.
Những gì được coi là một khối có thể tránh được—và điều gì nên dừng công việc
Một khối có thể tránh được là một sự từ chối liên quan đến hành vi thu thập mà dự án có thể chính đáng sửa chữa, chẳng hạn như gửi yêu cầu nhanh hơn mức ngân sách đã đồng ý. Một ranh giới ủy quyền là khác. Nếu việc truy cập yêu cầu sự cho phép mà dự án không có, phản ứng đúng là dừng lại và có được một lộ trình đã được chấp thuận.
Giao thức loại trừ robots định nghĩa các hướng dẫn cho công cụ thu thập và phân biệt chúng rõ ràng với ủy quyền truy cập. Đọc các quy tắc áp dụng trước khi khám phá, nhưng cũng xem lại các điều khoản nguồn, mục đích sử dụng và bất kỳ sự cho phép bằng văn bản nào. Dừng lại trên một lộ trình không được phép ngay cả khi một phần khác của trang web được cho phép.
Phân loại các lỗi trước khi quyết định thử lại:
Quan sát
Bước tiếp theo thích hợp
Suy diễn không thích hợp
Cần xác thực hoặc truy cập bị cấm
Dừng lại và xem xét lộ trình truy cập đã được chấp thuận
Mọi sự từ chối đều là lỗi mạng tạm thời
Phản hồi giới hạn tần suất
Tôn trọng hướng dẫn thời gian và giảm áp lực gửi
Một danh tính khác được cấp phép để tiếp tục
Quá tải dịch vụ tạm thời
Hoãn lại dưới một chính sách đã giới hạn
Thử lại ngay lập tức từ mỗi công nhân
Tài nguyên bị thiếu
Ghi nhận sự vắng mặt của tài nguyên đó
Một mục phải không khả dụng trong thế giới thực
Trang thành công không mong đợi
Cách ly và kiểm tra danh tính/nội dung nguồn
Thành công HTTP chứng minh thành công trong việc trích xuất
Đây là các quy tắc vận hành, không phải là tư vấn pháp lý hoặc là một sự thay thế cho một thỏa thuận cụ thể với nguồn. Nếu dự án không chắc chắn về ủy quyền, hãy giữ cho việc thu thập bị tạm dừng trong khi sự không chắc chắn đó được giải quyết.
Hướng dẫn Chi tiết
Luồng công việc thực tế bên dưới bắt đầu với ủy quyền và kết thúc với các bản ghi chấp nhận. Nó tách biệt phạm vi, lập lịch yêu cầu, kết quả thu thập và xác thực nội dung để các lỗi không trở thành các thay đổi dữ liệu im lặng.
Phương pháp 1: Giảm tải công việc trước khi gửi yêu cầu
Bước 1: Định nghĩa dân số được chấp thuận
Liệt kê các nguồn gốc, đường dẫn, loại URL đầu vào, các trường dự định, số trang tối đa và các điều kiện dừng được phép. Từ chối các URL ngoài hợp đồng đó khi gửi, không chỉ sau khi chúng vào hàng đợi. Đừng chấp nhận các URL do người dùng cung cấp vào một bộ thu thập không bị hạn chế; một hệ thống sản xuất cũng cần có các biện pháp bảo vệ cấp mạng chống lại các điểm đến nội bộ hoặc bị cấm khác.
Sử dụng một nguồn cấp, xuất khẩu hoặc API được ủy quyền khi nó đáp ứng nhiệm vụ. Một nguồn gia tăng được phép có thể giảm bớt công việc thu thập hiệu quả hơn so với việc tối ưu hóa một lần thu thập lớn không cần thiết. Thảo luận quá trình thu thập danh sách cung cấp ngữ cảnh hữu ích cho việc khám phá cần phải giữ được giới hạn.
Bước 2: Chuẩn hóa mà không làm mất ý nghĩa
Giải quyết các liên kết tương đối và loại bỏ các mảnh thừa khi thích hợp, nhưng không loại bỏ mọi tham số truy vấn. Một biến thể, ngữ cảnh tìm kiếm, hoặc con trỏ phân trang có thể mang ý nghĩa. Đừng trùng lặp theo các quy tắc nguồn đã được xem xét và giữ lại URL gốc làm bằng chứng.
Theo dõi số lượng được phát hiện, nộp, lấy về và được chấp nhận một cách độc lập. Nếu việc khám phá tạo ra nhiều URL nhưng chỉ một tập hợp nhỏ được review là hữu ích, hãy giảm biên giới trước khi tăng khả năng yêu cầu. Việc hoàn thành một hàng đợi không có nghĩa là hoàn tất trang web.
Bước 3: Sử dụng bộ nhớ đệm và thu thập gia tăng
Giữ lại siêu dữ liệu phản hồi hữu ích và các vật thể đã được chấp nhận trước đó. Nơi được hỗ trợ và phù hợp, các yêu cầu có điều kiện sử dụng bộ xác thực có thể giảm nội dung chuyển giao; một kết quả không bị thay đổi nên tham chiếu đến vật thể đã lưu thay vì trở thành một bản ghi trang trống.
Bộ nhớ đệm không phải là một chính sách tươi mới toàn cầu. Định nghĩa độ tuổi tối đa của một bản ghi có thể được sử dụng, và làm mới các nguồn có sự thay đổi quan trọng đối với ứng dụng. Một trợ lý chính sách và một thư mục ít thay đổi có thể hợp pháp sử dụng các lịch trình khác nhau.
Phương pháp 2: Làm cho nhịp độ và trạng thái cuối rõ ràng
Bước 1: Đặt cổng tốc độ bên ngoài mỗi công nhân
Sử dụng một trình lập lịch ở mức nguồn chia sẻ khi nhiều công nhân hoặc dịch vụ có thể chạm vào cùng một nguồn. Độ trễ per-worker không bảo vệ tỷ lệ tổng thể: nhiều nhiệm vụ nhìn lịch sự có thể tạo ra một sự bùng nổ tập thể. Trình lập lịch nên tính đến việc thử lại và các yêu cầu từ trình duyệt nơi thời gian chạy đã chọn phơi bày công việc đó.
Tài liệu Scrapy AutoThrottle mô tả hành vi độ trễ thích ứng và sự tương tác của nó với các cài đặt đồng thời. Thay đổi thích ứng là một công cụ quản lý tải, không phải là sự cho phép vượt quá các điều kiện truy cập đã thỏa thuận.
Bước 2: Tôn trọng Retry-After mà không rút ngắn
Tài liệu đặc tả ngữ nghĩa HTTP mô tả Retry-After như một giá trị độ trễ hoặc một ngày HTTP. Phân tích cả hai hình thức. Nếu độ trễ yêu cầu vượt quá ngân sách chờ của công việc, hãy hoãn công việc thay vì giới hạn độ trễ về một giá trị ngắn hơn và thử lại sớm.
Đặt giới hạn cố gắng và một ngân sách hoạt động tổng thể. Một chính sách thử lại có giới hạn nên xác định những điều kiện nào có thể thử lại và chuyện gì xảy ra sau khi sử dụng hết. Thêm jitter chỉ ở những nơi tương thích với thời gian chờ tối thiểu của máy chủ và lịch trình đã thỏa thuận.
Bước 3: Dừng lại thay vì quay vòng qua các danh tính truy cập
Đừng xem phản hồi bị cấm hoặc thách thức truy cập như một hướng dẫn để quay vòng danh tính cho đến khi trang tải xong. Ghi lại trạng thái cuối, giảm hoặc ngừng khối lượng công việc gốc, và xem xét ủy quyền hoặc liên hệ với nhà điều hành nguồn. Bảo vệ thông tin xác thực bên ngoài các bản ghi và không thu thập nội dung tài khoản cá nhân.
Phương pháp 3: Chạy một ví dụ Python nhỏ, có thể kiểm tra
Bước 1: Hiểu các yêu cầu và giới hạn của ví dụ
Ví dụ sử dụng thư viện chuẩn của Python và trang chứng minh tài liệu công cộng tại example.com. Cần có quyền truy cập mạng. Nguồn được phê duyệt được mã cứng, các chuyển hướng không được theo dõi, và mỗi yêu cầu được định mức. Không thay thế nguồn hay các kiểm tra chính sách bằng một danh sách mục tiêu sản xuất rộng mà không có một đánh giá truy cập riêng biệt.
Bộ phân tích robots cục bộ rất hữu ích cho màn trình diễn giới hạn này; phần mềm sản xuất cần một triển khai phù hợp với toàn bộ Giao thức loại trừ Robots và chính sách riêng của nó. Mẫu không phải là một trình lập lịch phân tán, một công cụ thu thập của trình duyệt, hay một hệ thống phòng thủ SSRF hoàn chỉnh.
Bước 2: Thực hiện bộ thu thập giới hạn
Chương trình đầu tiên kiểm tra các hướng dẫn của trình thu thập, sau đó lấy về trang đã được phê duyệt duy nhất. Nó xem xét sự từ chối, chuyển hướng, nội dung bất ngờ, và việc thử lại đã cạn kiệt như là các kết quả rõ ràng. Các khẳng định được tích hợp sử dụng đầu vào tổng hợp để kiểm tra hành vi phân tích; chúng tách biệt với yêu cầu trang công khai trực tiếp.
"""Bounded tutorial demo: only the public example.com documentation page."""import json
import time
import urllib.error
import urllib.request
import urllib.robotparser
from datetime import datetime, timezone
from email.utils import parsedate_to_datetime
from urllib.parse import urlsplit
AGENT ='NstdataResearchTutorial/1.0'ALLOWED_ORIGIN ='https://example.com'MIN_INTERVAL =1.0MAX_WAIT =5.0MAX_BYTES =200_000classNoRedirect(urllib.request.HTTPRedirectHandler):defredirect_request(self, req, fp, code, msg, headers, newurl):returnNoneopener = urllib.request.build_opener(NoRedirect())last_start =Nonedefrequest(url):global last_start
parts = urlsplit(url)iff'{parts.scheme}://{parts.netloc}'!= ALLOWED_ORIGIN:raise ValueError('Địa chỉ URL nằm ngoài nguồn được phê duyệt rõ ràng')if last_start isnotNone: time.sleep(max(0.0, MIN_INTERVAL -(time.monotonic()- last_start))) last_start = time.monotonic() req = urllib.request.Request(url, headers={'User-Agent': AGENT})return opener.open(req, timeout=10)defretry_delay(value, now=None): now = now or datetime.now(timezone.utc)if value isNone:returnNone value = value.strip()if value.isdigit():returnfloat(value)
try:
when = parsedate_to_datetime(value)
if when.tzinfo is None:
when = when.replace(tzinfo=timezone.utc)
return max(0.0, (when - now).total_seconds())
except (TypeError, ValueError, OverflowError):
return None
def robots_allow(url):
robots_url = ALLOWED_ORIGIN + '/robots.txt'
try:
with request(robots_url) as response:
body = response.read(MAX_BYTES + 1)
if len(body) > MAX_BYTES:
return False
except urllib.error.HTTPError as error:
if error.code in (404, 410):
return True # Tệp robots không có sẵn; quyền vẫn tách riêng.
return False # Dừng cẩn thận cho từ chối, quá tải, và chuyển hướng.
except (urllib.error.URLError, TimeoutError):
return False
parser = urllib.robotparser.RobotFileParser()
parser.parse(body.decode('utf-8', 'replace').splitlines())
return parser.can_fetch(AGENT, url)
def collect(url):
if not robots_allow(url):
return {'url': url, 'outcome': 'robots_or_policy_stop'}
for attempt in range(2):
try:
with request(url) as response:
content_type = response.headers.get('Content-Type', '')
data = response.read(MAX_BYTES + 1)
status = response.status
if len(data) > MAX_BYTES:
return {'url': url, 'outcome': 'size_stop'}
if 'text/html' not in content_type.lower():
return {'url': url, 'outcome': 'unexpected_content_type'}
text = data.decode('utf-8', 'replace')
if 'Example Domain' not in text:
return {'url': url, 'outcome': 'unexpected_content'}
return {'url': url, 'outcome': 'accepted', 'http_status': status,
'bytes': len(data), 'attempt': attempt + 1,
'captured_at': datetime.now(timezone.utc).isoformat()}
except urllib.error.HTTPError as error:
delay = retry_delay(error.headers.get('Retry-After'))
if error.code not in (429, 503) or attempt == 1:
return {'url': url, 'outcome': 'terminal_http_stop',
'http_status': error.code}
if delay is None or delay > MAX_WAIT:
return {'url': url, 'outcome': 'deferred_to_operator',
'http_status': error.code}
time.sleep(delay) # Không bao giờ rút ngắn thời gian trì hoãn yêu cầu của máy chủ.
except (urllib.error.URLError, TimeoutError) as error:
return {'url': url, 'outcome': 'transport_stop',
'error_type': type(error).name}
if name == 'main':
fixed = datetime(2026, 1, 1, tzinfo=timezone.utc)
assert retry_delay('3', fixed) == 3.0
assert retry_delay('Thu, 01 Jan 2026 00:00:04 GMT', fixed) == 4.0
assert retry_delay('invalid', fixed) is None
blocked = urllib.robotparser.RobotFileParser()
blocked.parse(['User-agent: *', 'Disallow: /private/'])
assert not blocked.can_fetch(AGENT, ALLOWED_ORIGIN + '/private/file')
print(json.dumps({'unit_checks': 4, 'live_result': collect(ALLOWED_ORIGIN + '/')}, indent=2))
Bước 3: Diễn giải kết quả một cách trung thực
Chạy ghi lại và đầu ra chính xác của nó được lưu trữ cùng với các hiện vật xác minh của bài viết này. Sự chấp nhận có nghĩa là ví dụ nhỏ này đã đạt được nội dung HTML mong đợi của nó theo chính sách đã định. Nó không chứng minh quyền truy cập, thông lượng, hoặc tính phù hợp cho một nguồn không liên quan.
Đối với một bản ghi sản xuất, giữ nguyên danh tính nguồn, thời gian thu thập, kết quả phản hồi, phiên bản chuyển đổi, và tham chiếu hiện vật. Một trang chứa thông báo đăng nhập hoặc một tiếng gọi không liên quan không nên cập nhật bản ghi sản phẩm, công việc, hoặc tài liệu. Hướng dẫn crawlers mã nguồn mở giúp xác định trách nhiệm khung mà đoạn mã nhỏ này cố ý để lại.
Nstdata Crawl khi hoạt động của công nhân thu thập không phải là mục tiêu
Nstdata Crawl là một tùy chọn được quản lý cho việc thu thập trang đã được phê duyệt và khám phá trang giới hạn. Nó có thể trình bày nội dung công khai khi tài liệu yêu cầu không có sẵn từ HTML ban đầu và trả về các đại diện được chọn để phân tích hoặc xem xét. Các điều khiển trang và độ sâu của nó giúp thể hiện ngân sách thu thập trước khi công việc mở rộng. Dịch vụ có thể giảm bớt trình duyệt và hạ tầng thu thập mà một nhóm vận hành, trong khi ứng dụng vẫn giữ quyền truy cập, diễn giải lĩnh vực, và quy tắc chấp nhận. Nó không đảm bảo rằng một mục tiêu sẽ cho phép thu thập hoặc biến từ chối truy cập thành ủy quyền.
Phạm vi trước khi thực hiện
Chọn các trang được phép, giới hạn rõ ràng, và quy tắc bao gồm/loại trừ trước khi gửi khối lượng công việc. Đối xử với kết quả khám phá của nhà cung cấp như một biên giới ứng viên thay vì một mở rộng tự động của quyền truy cập.
Hiện vật trước khi diễn giải
Giữ các tài nguyên nguồn tách biệt với các hồ sơ kinh doanh đã được chấp nhận. Sử dụng nội dung dễ đọc cho xử lý tài liệu và bằng chứng HTML hoặc hình ảnh khi kiểm tra sự bất đồng phân tích. Một định dạng đầu ra đã chọn không đảm bảo tính hoàn chỉnh ngữ nghĩa.
Chi phí và kiểm soát trước quy mô
Xem xét mô hình sử dụng Crawl và tính đến việc thu thập theo URL cùng với việc sử dụng proxy áp dụng. Đo lường các hồ sơ đã chấp nhận và nội dung bị từ chối song song với số lượng yêu cầu. Tăng khối lượng công việc chỉ khi chính sách nguồn, lịch trình, và xác thực hạ lưu có thể hỗ trợ nó.
Kết luận: ít yêu cầu hơn và các điểm dừng rõ ràng là những cải thiện hữu ích
Việc thu thập có trách nhiệm giảm thiểu các khối không cần thiết bằng cách loại bỏ việc thu thập không cần thiết, phối hợp tốc độ ở mức nguồn, tôn trọng thời gian máy chủ, và dừng lại khi bị từ chối truy cập. Chạy một mẫu đã được phê duyệt qua toàn bộ lộ trình phát hiện đến chấp nhận trước khi lên lịch thêm các trang. Quản lý Proxy Nstdata là có liên quan khi dự án cần định tuyến tập trung và khả năng nhìn thấy hoạt động trên các khối lượng thu thập đã được ủy quyền.
Xem xét một lần thu thập được phê duyệt có giới hạn
Đánh giá Nstdata Crawl trên một tập trang nhỏ đã được phê duyệt và kiểm tra cả kết quả thành công và kết quả cuối cùng trước khi mở rộng quy mô.
H: Liệu việc thu thập có trách nhiệm có thể đảm bảo không có khối nào không?
Không. Một nguồn có thể từ chối hoặc hạn chế quyền truy cập. Hoạt động có trách nhiệm giảm thiểu tải trọng và lỗi không cần thiết nhưng phải tôn trọng quyết định đó.
H: Quyền trong robots.txt có cho phép mọi sử dụng nội dung không?
Không. Hướng dẫn thu thập, quyền truy cập, quyền tái sử dụng nội dung, và mục đích sử dụng là những mối quan tâm riêng biệt.
H: Có nên thử lại một phản hồi bị cấm với proxy khác không?
Không nên như một cách để vượt qua một sự từ chối. Dừng lại và xem xét lộ trình truy cập đã được phê duyệt thay vì luân chuyển danh tính để làm cho thành công.
H: Nếu Retry-After vượt quá ngân sách chờ của công việc thì sao?
Trì hoãn hoặc dừng công việc. Không rút ngắn thời gian chờ của máy chủ chỉ để phù hợp với một vòng lặp thử lại cục bộ.
H: Phản hồi HTTP thành công có phải là một vụ thu thập thành công không?
Không. Xác thực loại nội dung, danh tính nguồn, các trường yêu cầu, và nội dung dự phòng không mong đợi trước khi chấp nhận một hồ sơ.
H: Mẫu Python có thực hiện việc thu thập quy mô sản xuất không?
Không. Nó chỉ ra một nguồn có giới hạn, các điểm dừng rõ ràng và kiểm tra nội dung. Lịch trình phân tán, xử lý chính sách mạnh mẽ, tính kiên trì, và bảo vệ mạng cần có kỹ thuật bổ sung.
Việc thu thập có trách nhiệm bắt đầu với ít yêu cầu không cần thiết hơn và các điều kiện dừng rõ ràng. Theo một ví dụ Python có giới hạn, phân biệt ủy quyền với quá tải, và xác thực nội dung trước khi chấp nhận hồ sơ.
Lena Zhou
Oct. 14th 2026
Trải nghiệm Nstproxy Crawl - Bắt Đầu Dùng Thử Miễn Phí Hôm Nay
Thu thập toàn bộ trang web chỉ với một yêu cầu API
Chuyển mọi trang web thành Markdown, HTML, JSON, liên kết, PDF và hơn thế nữa mà không cần quản lý hạ tầng thu thập dữ liệu.
Tỷ lệ thành công 99,8% với kết xuất JavaScript
Nhận dữ liệu sạch, sẵn sàng cho LLM ở nhiều định dạng