🎯 Trình duyệt đám mây tùy chỉnh, chống phát hiện được hỗ trợ bởi Chromium tự phát triển, thiết kế dành cho trình thu thập dữ liệu webtác nhân AI. 👉Dùng thử ngay
Quay lại blog

Ollama Web Scraping: Chạy một Trình thu thập thông tin LLM cục bộ mà không cần khóa API

Alex Johnson
Alex Johnson

Senior Web Scraping Engineer

23-Jul-2026

Tóm tắt:

  • Ollama chạy mô hình trích xuất trên máy của bạn, vì vậy bước LLM của một trình thu thập không tốn API key và không có hóa đơn theo token.
  • Điều mà Ollama không làm là lấy dữ liệu. Một mô hình cục bộ không có trình duyệt và không thể truy cập vào một trang; nó cấu trúc văn bản mà bạn cung cấp.
  • Sự khác biệt xuất hiện trong một script. Một yêu cầu GET đơn giản trên một trang demo được render bằng JavaScript cho bạn 0 khối trích dẫn; cùng một URL thông qua Scrapeless Universal Scraping API với js_render cho bạn tất cả 10 — và HTML được render đó là những gì mô hình đọc.
  • Quá trình trích xuất là có thật trong hướng dẫn này. Một lần chạy thực tế cung cấp ba khối trích dẫn đã được render cho mô hình cục bộ qwen2.5:0.5b và nhận về JSON sạch với văn bản và tác giả của mỗi khối — không có cuộc gọi nào tới cloud.
  • Mô hình nhỏ muốn ít nhiễu hơn. Cắt HTML để tới vùng nội dung trước khi mô hình nhìn thấy nó; một mô hình 0.5B trên một đoạn tập trung là nhanh và chính xác, trong khi toàn bộ trang sẽ không vừa.
  • Miễn phí để bắt đầu ở phía lấy dữ liệu. Tạo API key Scrapeless của bạn tại app.scrapeless.com.

Tại sao chạy mô hình của trình thu thập ở chế độ cục bộ

Một trình thu thập LLM biến nội dung trang thành các bản ghi có cấu trúc, và mô hình đó không nhất thiết phải sống trong cloud của người khác. Ollama chạy các mô hình mở trên phần cứng của bạn thông qua một API HTTP nhỏ, vì vậy bước trích xuất không cần API key, không giới hạn tỷ lệ, và không tốn phí theo token — hữu ích khi bạn xử lý nhiều trang hoặc xử lý dữ liệu mà bạn không muốn gửi đến bên thứ ba.

Điều mà một mô hình cục bộ không thể làm là lấy dữ liệu. Nó không có trình duyệt, không duy trì phiên làm việc, và trên một trang được render bằng JavaScript, một yêu cầu HTTP đơn giản trả về mã lập trình mà không có nội dung nào trong đó. Vì vậy, một trình thu thập web Ollama là hai lớp: một lớp lấy dữ liệu trả về HTML đã render trung thực, và mô hình cục bộ như là lớp trích xuất biến nó thành các bản ghi. Hướng dẫn này sử dụng Scrapeless Universal Scraping API cho lớp đầu tiên. Nếu thay vào đó bạn muốn cung cấp cho mô hình cục bộ một tìm kiếm web trực tiếp — mô hình gọi một công cụ tìm kiếm và lý luận qua các kết quả — đó là một công việc khác, được đề cập trong hướng dẫn tìm kiếm web LLM cục bộ; bài viết này nói về việc trích xuất dữ liệu có cấu trúc từ một trang cụ thể.

Điều kiện tiên quyết

  • Ollama đã được cài đặt và đang chạy, với một mô hình thân thiện với công cụ nhỏ được tải xuống: ollama pull qwen2.5:0.5b.
  • Python 3.9 trở lên với requests.
  • Một API key Scrapeless từ bảng điều khiển, được xuất như SCRAPELESS_API_KEY.

Cài đặt

Tải một mô hình nhỏ và cài đặt một phụ thuộc Python. Máy chủ Ollama lắng nghe trên localhost:11434 khi nó đang chạy.

bash Copy
ollama pull qwen2.5:0.5b
pip install requests

Giữ key của bạn trong môi trường, không bao giờ trong mã nguồn:

bash Copy
export SCRAPELESS_API_KEY="sk_your_scrapeless_key"

Lấy một trang mà mô hình thực sự có thể đọc

Chất lượng trích xuất bị giới hạn bởi độ fidelity lấy dữ liệu, vì vậy bắt đầu ở đó. Trên một trang được render bằng JavaScript, tài liệu mà một client HTTP đơn giản nhận được không phải là tài liệu mà một người đọc thấy — nội dung chỉ xuất hiện sau khi các script xây dựng DOM, một chu kỳ sống được định nghĩa bởi các đặc tả về scripting HTML. Một script đếm sự khác biệt:

python Copy
# fetch_rendered.py — GET đơn giản so với render phía máy chủ, cùng một URL
import os

import requests

URL = "https://quotes.toscrape.com/js/"
MARKER = '<div class="quote">'

plain = requests.get(URL, timeout=60).text
print("số ký tự GET đơn giản:", len(plain), "| khối trích dẫn:", plain.count(MARKER))

resp = requests.post(
    "https://api.scrapeless.com/api/v2/unlocker/request",
    headers={"Content-Type": "application/json", "x-api-token": os.environ["SCRAPELESS_API_KEY"]},
    json={"actor": "unlocker.webunlocker", "input": {"url": URL, "js_render": True}},
    timeout=120,
)
resp.raise_for_status()
rendered = resp.json().get("data", "")
print("số ký tự đã render:", len(rendered), "| khối trích dẫn:", rendered.count(MARKER))

Chạy lệnh in ra 0 khối trích dẫn cho yêu cầu lấy dữ liệu đơn giản và 10 cho yêu cầu đã render:

text Copy
số ký tự GET đơn giản: 5806 | khối trích dẫn: 0
số ký tự đã render: 8940 | khối trích dẫn: 10

Việc render, mở khóa, và định tuyến proxy đều xảy ra ở phía máy chủ trong một POST đó — Universal Scraping API là lớp lấy dữ liệu, và HTML đã render là nội dung mà mô hình cục bộ trích xuất từ.

Trích xuất với mô hình cục bộ

Bây giờ hãy chuyển nội dung cho Ollama. Hai điều giữ cho một mô hình nhỏ chính xác: cắt HTML thành khu vực nội dung để mô hình không đọc giao diện trang, và yêu cầu JSON với format: "json" để đầu ra có thể phân tích. Điểm cuối /api/generate của Ollama nhận tên mô hình và lời nhắc, sau đó trả về kết quả, được tài liệu hóa trong tài liệu tham khảo API của Ollama:

python Copy
# extract_local.py — lấy, cắt và trích xuất với một mô hình Ollama cục bộ
import json
import os
import re

import requests

resp = requests.post(
    "https://api.scrapeless.com/api/v2/unlocker/request",
    headers={"Content-Type": "application/json", "x-api-token": os.environ["SCRAPELESS_API_KEY"]},
    json={"actor": "unlocker.webunlocker", "input": {"url": "https://quotes.toscrape.com/js/", "js_render": True}},
    timeout=120,
)
resp.raise_for_status()
html = resp.json().get("data", "")

# Cắt đến ba khối trích dẫn đầu tiên — một mô hình cục bộ nhỏ hoạt động tốt hơn với ít tạp âm hơn.
blocks = re.findall(r'<div class="quote">.*?</small>', html, re.S)[:3]
snippet = "\n".join(blocks)

completion = requests.post(
    "http://localhost:11434/api/generate",
    json={
        "model": "qwen2.5:0.5b",
        "prompt": 'Trích xuất mọi trích dẫn từ HTML này thành JSON với hình dạng chính xác '
                  '{"quotes":[{"text":"...","author":"..."}]}. Trả lời chỉ với JSON.\n\nHTML:\n' + snippet,
        "stream": False,
        "format": "json",
        "options": {"temperature": 0, "num_predict": 400},
    },
    timeout=600,
)
data = json.loads(completion.json()["response"])

records = data["quotes"]
print("records:", len(records))
print("first author:", records[0]["author"])
print("first text:", records[0]["text"])

Chạy cục bộ trả về ba bản ghi, với văn bản và tác giả còn nguyên vẹn ở bản đầu tiên:

text Copy
records: 3
first author: Albert Einstein
first text: Thế giới mà chúng ta đã tạo ra là một quá trình suy nghĩ của chúng ta. Nó không thể được thay đổi mà không thay đổi suy nghĩ của chúng ta.

Đó là toàn bộ trình thu thập thông tin, và phần mô hình chưa bao giờ chạm đến mạng: một POST đến Scrapeless để lấy và render, một cuộc gọi đến localhost để trích xuất. Quy mô số lượng khối mỗi lần gọi tới khả năng phần cứng của bạn — một mô hình 0.5B trên CPU chậm hơn một điểm cuối đám mây, vì vậy hãy batch nhỏ và giữ cho đầu vào chặt chẽ.

Nhận khóa API của bạn trong kế hoạch miễn phí: app.scrapeless.com

Mô hình nâng cao

  • Khớp mô hình với phần cứng. qwen2.5:0.5b đủ nhanh để trình diễn trên CPU; một mô hình 3B hoặc 7B trích xuất đáng tin cậy hơn từ các trang lộn xộn nếu bạn có bộ nhớ và kiên nhẫn. Hình dạng yêu cầu không thay đổi — chỉ có chuỗi model là thay đổi.
  • Cắt trước khi bạn yêu cầu. Tách biệt vùng nội dung là đặc điểm chất lượng lớn nhất đối với một mô hình nhỏ. Gửi khối lặp lại, không phải toàn bộ tài liệu, và cả chi phí token lẫn tỷ lệ lỗi đều giảm.
  • Giữ format: "json"temperature: 0. Chế độ JSON ràng buộc đầu ra ở dạng JSON có thể phân tích, và nhiệt độ bằng không giữ cho việc trích xuất ổn định qua các lần chạy; cả hai đều không thể thiếu cho một trình thu thập thông tin.
  • Lặp lại trong Python, không phải trong lời nhắc. Một vùng nội dung cho mỗi yêu cầu giữ cho các bản ghi không bị chồng chéo và làm cho việc trích xuất kém có thể quy cho một trang cụ thể.

Khắc phục sự cố

  • Connection refused trên localhost:11434. Máy chủ Ollama không chạy. Khởi động nó (ollama serve) và xác nhận mô hình đã được kéo với ollama list.
  • Không có khối nào để trích xuất. Lấy của bạn đã trả về HTML chưa được render. Đếm một phần tử đã biết theo cách mà script đầu tiên làm; một yêu cầu gần như rỗng là một vấn đề render, được khắc phục với js_render, không phải là vấn đề của mô hình.
  • Mô hình trả về văn xuôi, không phải JSON. Bạn đã bỏ qua format: "json". Với nó, Ollama ràng buộc đầu ra; không có nó, bạn đang phân tích lòng tốt.
  • Việc trích xuất chậm hoặc mất bản ghi. Mô hình quá nhỏ cho kích thước đầu vào. Cắt xuống ít khối hơn cho mỗi lần gọi, hoặc chuyển sang một mô hình lớn hơn — các mô hình cục bộ nhỏ đánh đổi độ chính xác để lấy tốc độ, và một lời nhắc ngắn hơn, rõ ràng hơn là cách lấy lại cả hai.

Kết luận

Ollama xứng đáng có vị trí như lớp trích xuất hoạt động nơi bạn làm việc: chạy các mô hình mở trên phần cứng của riêng bạn, không cần key và không phải trả tiền theo token, biến nội dung trang thành JSON. Lớp quyết định bất kỳ điều gì trong số đó có thể thực hiện là việc lấy — đếm 0 so với 10 của script đầu tiên quyết định điều đó — và một POST được render từ máy chủ đóng khoảng cách. Kết nối hai thứ này lại với nhau và một trang được render trở thành các bản ghi có cấu trúc, với phần mô hình hoàn toàn ở trên localhost.
Tạo một tài khoản Scrapeless miễn phí để nhận khóa API, và tài liệu cho nhà phát triển bao gồm các tham số unlocker.webunlocker. Kiểm tra giá cả của Scrapeless khi bạn lên kế hoạch cho một công việc định kỳ.

Câu hỏi thường gặp

Q: Ollama có thể tự động thu thập dữ liệu từ các trang web không?

Không. Ollama chạy một mô hình ngôn ngữ cục bộ; nó không có trình khách HTTP cho các trang tùy ý và không thể kết xuất JavaScript. Nó cấu trúc văn bản mà bạn cung cấp. Kết hợp nó với một lớp truy xuất — ở đây là API Thu thập Dữ liệu Toàn cầu của Scrapeless, xử lý trang ở phía máy chủ — và mô hình cục bộ sẽ thực hiện việc trích xuất.

Q: Điều này khác gì so với việc sử dụng LLM cục bộ để tìm kiếm web?

Hướng đi. Một thiết lập tìm kiếm web cho phép mô hình gọi một công cụ tìm kiếm và lý luận qua các kết quả để trả lời câu hỏi; thiết lập này lấy một trang cụ thể mà bạn chọn và cho mô hình trích xuất các trường có cấu trúc từ nó. Một cái là trả lời được tăng cường tìm kiếm, cái còn lại là quy trình thu thập dữ liệu — hướng dẫn tìm kiếm web LLM cục bộ liên kết ở trên bao gồm cái đầu tiên.

Q: Tôi nên sử dụng mô hình cục bộ nào để trích xuất?

Mô hình nhỏ nhất mà giữ được sơ đồ của bạn. Việc trích xuất với một lời nhắc JSON nghiêm ngặt và temperature: 0 không yêu cầu lý luận nặng nề, vì vậy một mô hình 0.5B hoạt động trên một đoạn đã được rút gọn, như trong ví dụ trên. Chuyển sang mô hình 3B hoặc lớn hơn chỉ khi các trang không gọn gàng đủ để mô hình nhỏ mất trường.

Q: Tôi có cần GPU không?

Không. Lần chạy trong hướng dẫn này sử dụng mô hình 0.5B trên CPU. Một GPU làm cho các mô hình lớn hơn thực tế và mọi thứ nhanh hơn, nhưng một mô hình nhỏ trên CPU là đủ để xây dựng và thử nghiệm quy trình.

Q: Việc thu thập dữ liệu bằng mô hình cục bộ có hợp pháp không?

Việc chạy mô hình cục bộ không thay đổi các quy tắc thu thập dữ liệu. Chỉ lấy các trang công khai, tôn trọng các điều khoản của trang và những chỉ thị robot theo tiêu chuẩn được quy định bởi Giao thức loại trừ Robot, giữ khối lượng hạn chế, và xử lý bất kỳ dữ liệu cá nhân nào theo các luật áp dụng cho bạn.

Tại Scrapless, chúng tôi chỉ truy cập dữ liệu có sẵn công khai trong khi tuân thủ nghiêm ngặt các luật, quy định và chính sách bảo mật trang web hiện hành. Nội dung trong blog này chỉ nhằm mục đích trình diễn và không liên quan đến bất kỳ hoạt động bất hợp pháp hoặc vi phạm nào. Chúng tôi không đảm bảo và từ chối mọi trách nhiệm đối với việc sử dụng thông tin từ blog này hoặc các liên kết của bên thứ ba. Trước khi tham gia vào bất kỳ hoạt động cạo nào, hãy tham khảo ý kiến ​​cố vấn pháp lý của bạn và xem xét các điều khoản dịch vụ của trang web mục tiêu hoặc có được các quyền cần thiết.

Bài viết phổ biến nhất

Danh mục