Quay lại blog

Thu thập dữ liệu web với Java: Jsoup, Playwright và các quy trình Cloud Browser

Ava Wilson
Ava Wilson

Expert in Web Scraping Technologies

10-Oct-2026

Tóm tắt nhanh:

  • Jsoup phân tích HTML được cung cấp cho nó. Nó không chạy JavaScript của trang để tạo các bản ghi còn thiếu.
  • Playwright Java cung cấp một đường dẫn lấy dữ liệu qua trình duyệt. HTML sau khi render có thể đưa vào cùng một hợp đồng trích xuất Jsoup dùng cho trang tĩnh.
  • Agent Browser chuyển việc thực thi trình duyệt lên đám mây. Java vẫn kiểm soát selectors, kiểm tra bản ghi, phạm vi phân trang và xuất dữ liệu.
  • Tệp CSV chỉ hữu ích khi các bản ghi của nó nhận diện được nguồn dự định. Giữ nguyên các ID bản ghi ổn định và URL đã được resolve, và loại bỏ các bản ghi thiếu trường bắt buộc.

Việc web scraping bằng Java bắt đầu bằng một câu hỏi thực tế: HTML từ server đã chứa các bản ghi chưa, hay cần một trình duyệt để tạo ra chúng? Chọn đúng đường dẫn lấy dữ liệu giúp tránh viết selector cho một tài liệu vốn chưa bao giờ chứa dữ liệu đó.

Quy trình này dùng Jsoup để trích xuất và Playwright Java để lấy trang đã render. Cả hai đường dẫn đều tạo ra cùng một dạng bản ghi. Kết nối Scrapeless Agent Browser chuyên dụng là tùy chọn trên đám mây khi khối lượng công việc trình duyệt nên chạy bên ngoài môi trường host ứng dụng của bạn.

Các ví dụ nhắm tới một danh sách bài viết được kiểm soát với thuộc tính ổn định. Chỉ thay thế hợp đồng đó sau khi bạn đã kiểm tra nguồn được phép của mình. Biên dịch Java và thực thi trình duyệt yêu cầu runtime và thông tin xác thực liệt kê bên dưới; hướng dẫn này không tuyên bố có bắt Java trực tiếp trong môi trường thật.

Chọn Jsoup hay Trình duyệt dựa trên Nội dung Thực tế của Trang

Chọn Jsoup khi các bản ghi cần thiết đã có trong HTML nhận được. Chọn trình duyệt khi trang được phép yêu cầu JavaScript hoặc tương tác trước khi các bản ghi đó tồn tại.

Đường dẫn HTML cung cấp cho parser Nhiệm vụ khởi đầu phù hợp Trách nhiệm bạn giữ lại
Jsoup HTTP fetch Tài liệu do server trả về Danh sách bài viết hoặc danh mục tĩnh Kiểm tra nguồn và trích xuất
Playwright Java cục bộ Tài liệu do trình duyệt render Phát triển trang động có kiểm soát Runtime trình duyệt và quản lý tài nguyên
Agent Browser với Playwright Java Tài liệu từ trình duyệt trên đám mây Quy trình trình duyệt từ xa chuyên dụng Vòng đời kết nối, selectors và kiểm tra đầu ra

Đừng chọn đường dẫn dựa trên framework dùng để xây dựng site. Một ứng dụng JavaScript vẫn có thể phục vụ HTML hữu ích, trong khi một danh sách trông đơn giản có thể chèn bản ghi sau khi tải. Hãy kiểm tra trang cụ thể và các trường bạn cần.

Ngữ nghĩa biểu diễn HTTP mô tả phản hồi mà client nhận được. Trạng thái trang được tạo sau đó bởi trình duyệt là một quan sát lấy dữ liệu khác.

Điều kiện tiên quyết và Phụ thuộc

Dự án này cần JDK và Maven, cùng với các phụ thuộc Jsoup và Playwright Java. Dự án minh họa nhắm tới JDK 17; nó cố định Jsoup 1.23.2 và Playwright 1.63.0 thay vì tái sử dụng phiên bản từ một hướng dẫn cũ.

Đối với render cục bộ, hãy cài đặt runtime trình duyệt mà phiên bản Playwright của bạn yêu cầu trong môi trường dự án riêng của bạn. Đối với render từ xa, hãy lấy một kết nối Agent Browser chuyên dụng thông qua thiết lập tài khoản hiện tại và giữ nguyên endpoint đầy đủ của nó trong SCRAPELESS_CDP_URL.

Mục tiêu phải là công khai hoặc được ủy quyền theo cách khác. TARGET_URL là một URL danh sách bài viết được phép mà bạn đã kiểm tra cấu trúc. Hợp đồng selector của ví dụ là main article[data-id], với một heading và một link bên trong mỗi bài viết.

Lưu ý: Chuỗi công cụ Java, cài đặt phụ thuộc và runtime trình duyệt là các điều kiện tiên quyết để thực thi. Các đoạn mã đã được kiểm tra so với giao diện thư viện hiện tại nhưng không được biên dịch hoặc chạy trong môi trường xác minh sẵn có. Đường dẫn từ xa cũng yêu cầu một kết nối Scrapeless chuyên dụng thực.

Lưu cấu hình Maven này thành pom.xml và class bên dưới thành src/main/java/ArticleCollector.java:

xml Copy
<project xmlns="http://maven.apache.org/POM/4.0.0">
  <modelVersion>4.0.0</modelVersion>
  <groupId>example</groupId>
  <artifactId>article-collector</artifactId>
  <version>1.0.0</version>
  <properties>
    <maven.compiler.source>17</maven.compiler.source>
    <maven.compiler.target>17</maven.compiler.target>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
  </properties>
  <dependencies>
    <dependency>
      <groupId>org.jsoup</groupId>
      <artifactId>jsoup</artifactId>
      <version>1.23.2</version>
    </dependency>
    <dependency>
      <groupId>com.microsoft.playwright</groupId>
      <artifactId>playwright</artifactId>
      <version>1.63.0</version>
    </dependency>
  </dependencies>
  <build>
    <plugins>
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-compiler-plugin</artifactId>
        <version>3.10.1</version>
      </plugin>
    </plugins>
  </build>
</project>

Giữ nguyên mục tiêu compiler và phiên bản phụ thuộc trong dự án này để một môi trường khác có thể tái tạo thiết lập trước khi bất kỳ job thu thập nào được bật.

Cấu hình Một Hợp đồng Trích xuất cho Cả Hai Đường dẫn

Hợp đồng trích xuất định nghĩa một bản ghi bài viết được chấp nhận một cách độc lập với phương thức truyền tải. Ví dụ này yêu cầu data-id không rỗng, một heading h2, và một link resolve tới URL HTTP hoặc HTTPS.

Đây là các thuộc tính trong ví dụ có kiểm soát, không phải tuyên bố về các selectors hiện tại của một site công khai. Với nguồn của bạn, hãy ưu tiên các thuộc tính bản ghi ổn định hoặc mẫu URL bền vững khi có thể. Đừng tái sử dụng một class mang tính trang trí chỉ vì nó khớp với một lần bắt dữ liệu.

Giữ riêng các trường bắt buộc và tùy chọn. Thiếu định danh sẽ loại bỏ bản ghi ví dụ. Một phần tóm tắt tùy chọn có thể vắng mặt mà không làm thay đổi định danh bản ghi. Hãy đặt chính sách đó rõ ràng trước khi xuất dữ liệu.

Triển khai Cơ bản: Lấy, Trích xuất và Xuất

Class dưới đây lấy HTML thông qua đường dẫn đã chọn, trích xuất các bản ghi bài viết bằng Jsoup và ghi một tệp CSV UTF-8. Nhánh từ xa của nó dùng endpoint CDP do tài khoản cung cấp thay vì tự bịa ra một phương thức Java Scrapeless SDK.

Lưu ý: Ví dụ Java đầy đủ này yêu cầu các phụ thuộc đã được ghim, thiết lập JDK, Maven và một đích được cho phép. Nhánh local cần một môi trường chạy trình duyệt; nhánh remote cần SCRAPELESS_CDP_URL. Không có đầu ra nào bên dưới được trình bày như là kết quả thực thi trực tiếp.

java Copy
import com.microsoft.playwright.*;
import com.microsoft.playwright.options.WaitUntilState;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.net.URI;

public class ArticleCollector {
  private static String csv(String value) {
    return "\"" + value.replace("\"", "\"\"") + "\"";
  }

  public static void main(String[] args) throws Exception {
    if (args.length != 2) throw new IllegalArgumentException("mode and URL required");
    String mode = args[0];
    String target = args[1];
    Document doc;
    if (mode.equals("static")) {
      doc = Jsoup.connect(target).get();
    } else {
      if (!mode.equals("local") && !mode.equals("remote"))
        throw new IllegalArgumentException("Unsupported acquisition mode");
      try (Playwright playwright = Playwright.create()) {
        String endpoint = System.getenv("SCRAPELESS_CDP_URL");
        if (mode.equals("remote") && (endpoint == null || endpoint.isBlank()))
          throw new IllegalArgumentException("Dedicated CDP endpoint required");
        Browser browser = mode.equals("remote")
            ? playwright.chromium().connectOverCDP(endpoint)
            : playwright.chromium().launch();
        try {
          Page page = browser.newPage();
          page.navigate(target, new Page.NavigateOptions()
              .setWaitUntil(WaitUntilState.DOMCONTENTLOADED));
          page.locator("main article[data-id] a[href]").first().waitFor();
          doc = Jsoup.parse(page.content(), page.url());
        } finally {
          browser.close();
        }
      }
    }
    StringBuilder output = new StringBuilder("id,title,url\r\n");
    int accepted = 0;
    for (Element article : doc.select("main article[data-id]")) {
      Element heading = article.selectFirst("h2");
      Element link = article.selectFirst("a[href]");
      String id = article.attr("data-id").strip();
      if (id.isEmpty() || heading == null || link == null) continue;
      String title = heading.text().strip();
      String url = link.attr("abs:href");
      URI resolved = URI.create(url);
      if (title.isEmpty() || resolved.getHost() == null ||
          !("https".equals(resolved.getScheme()) || "http".equals(resolved.getScheme())))
        continue;
      output.append(csv(id)).append(',').append(csv(title)).append(',')
          .append(csv(url)).append("\r\n");
      accepted++;
    }
    if (accepted == 0) throw new IllegalStateException("Content contract not satisfied");
    Files.writeString(Path.of("articles.csv"), output, StandardCharsets.UTF_8);
    System.out.println("Accepted article records: " + accepted);
  }
}

Biên dịch dự án và sao chép các phụ thuộc của nó với Maven, sau đó chạy ArticleCollector bằng một classpath chứa target/classes và thư mục phụ thuộc. Chọn static, local hoặc remote và cung cấp URL mục tiêu đã kiểm tra của bạn.

Lưu ý: Các lệnh POSIX-shell này yêu cầu bộ công cụ Java và các phụ thuộc ở trên. Đặt TARGET_URL thành nguồn được cho phép. Biên dịch và thu thập vẫn là điều kiện tiên quyết để thực thi ví dụ này.

bash Copy
mvn -q dependency:copy-dependencies compile
java -cp 'target/classes:target/dependency/*' ArticleCollector static "$TARGET_URL"

Sử dụng dấu chấm phẩy làm bộ phân tách classpath trong môi trường Windows. Chỉ chọn chế độ local hoặc remote sau khi hoàn tất thiết lập môi trường chạy trình duyệt hoặc phiên chuyên dụng của nó.

Mã sử dụng abs:href để một liên kết tương đối được diễn giải dựa trên URL gốc của tài liệu đã thu. phân giải URI tương đối giải thích tại sao một đường dẫn tự thân không phải là một định danh nguồn hoàn chỉnh. Giữ lại URL trang đã lấy một cách tách biệt với từng URL bài viết được phát hiện trong bản kê khai thu thập của ứng dụng.

Kết xuất Trang Động với Playwright Java

Đường dẫn trình duyệt chờ một phần tử đặc thù cho tác vụ trước khi thu thập HTML của trang. domcontentloaded là mốc điều hướng; bộ định vị bài viết thiết lập điều kiện riêng rằng các bản ghi của ví dụ đã xuất hiện.

Đừng coi bất kỳ điều kiện nào là bằng chứng rằng mọi bản ghi đã đến. Một danh sách có thể tải thêm nhiều dòng chỉ sau một thao tác rõ ràng. Kiểm tra xem lô đầu tiên đã đầy đủ cho tác vụ được yêu cầu hay chưa trước khi chấp nhận nó.

Các phương thức kết nối trình duyệt Playwright phân biệt giao thức gốc của nó với CDP. Một kết nối CDP dành cho các trình duyệt dựa trên Chromium và có các khả năng khác với kết nối giao thức gốc của Playwright.

Giữ các thiết lập timeout và điều kiện sẵn sàng của nguồn trong cấu hình dự án khi phát triển một bộ thu thập thực tế. Một dấu hiệu hiển thị đặc thù từng nguồn hữu ích hơn nhiều so với việc chờ lưu lượng phân tích không liên quan trở nên nhàn rỗi.

Bắt đầu Thu thập Dữ liệu với Scrapeless

Tăng sức mạnh cho quy trình web scraping và tự động hóa của bạn với Scrapeless!
Đăng ký hôm nay và nhận 5$ tín dụng miễn phí — không cần thẻ tín dụng.

Nhận tín dụng miễn phí ngay trong Bảng điều khiển Scrapeless.

Nơi Các Trình Thu Thập Java Cục Bộ Dừng Lại

Trình phân tích Java cục bộ không thể cung cấp nội dung đã kết xuất còn thiếu, và một trình duyệt cục bộ không loại bỏ nhu cầu quản lý tài nguyên trình duyệt và trạng thái thu thập. Những giới hạn đó quyết định khi nào quy trình làm việc cần một trình duyệt đám mây.

Scrapeless Agent Browser cung cấp lớp trình duyệt từ xa cho quy trình Java này. Nhận một kết nối chuyên dụng thông qua thiết lập Agent Browser Playwright, sau đó truyền endpoint kết nối hoàn chỉnh cho nhánh remote.

URL kết nối có thể chứa thông tin xác thực. Giữ nó trong môi trường runtime, không ghi log, và chỉ đóng phiên chuyên dụng được cấp phát cho công việc này. Kết nối tới một trình duyệt dùng chung rồi đóng nó sẽ ảnh hưởng tới công việc khác đang sử dụng phiên đó.

Đường dẫn đám mây thay đổi nơi việc thu thập được thực thi. Nó vẫn giữ cùng việc phân tích HTML và xác thực bản ghi trong Java. Một tài liệu thử thách hoặc trạng thái trang không chính xác vẫn nên làm hỏng hợp đồng nội dung thay vì tạo ra một xuất dữ liệu thành công.

Khám Phá Liên kết và Phân Trang Có Giới Hạn

Phân trang nên tuân theo hợp đồng điều hướng đã được kiểm tra của nguồn và một phạm vi thu thập có giới hạn. Khám phá URL trang tiếp theo hoặc tương tác được cho phép từ nguồn thực tế thay vì đoán một tham số số trang.

Giữ lại định danh trang hiện tại, liên kết tiếp theo được phát hiện và tập hợp các trang đã truy cập. Xác nhận liên kết thuộc phạm vi nguồn đã được phê duyệt trước khi điều hướng. Dừng lại khi ngân sách số trang của tác vụ đã đạt, một URL lặp lại xuất hiện, hoặc nguồn khẳng định rằng không còn trang nào nữa.

Việc vắng mặt liên kết tiếp theo có thể có nghĩa là danh sách đã kết thúc hoặc nguồn không kết xuất được điều hướng của nó. Sử dụng nội dung trang và bằng chứng trạng thái trống để phân biệt các kết quả đó. Lớp một-trang ở trên cố ý để quyết định đó cho ứng dụng thay vì ngụ ý một vòng lặp phân trang mang tính phổ quát.

Xuất và xác thực các bản ghi

Bước xuất phải giữ nguyên danh tính của các bản ghi đã được chấp nhận và mã hóa đúng định dạng đã chọn. Các quy tắc trích dẫn trường CSV xử lý dấu phân cách và dấu ngoặc kép; ví dụ sẽ nhân đôi các dấu ngoặc kép lồng bên trong và đặt mỗi trường trong dấu ngoặc kép.

Cú pháp CSV tách biệt với việc xác thực nội dung. Mở lại đầu ra bằng bộ phân tích cú pháp phía sau dự kiến và kiểm tra các trường bắt buộc, định danh duy nhất và liên kết nguồn. Sử dụng chính sách nhập bảng tính giữ văn bản không tin cậy ở dạng dữ liệu khi sổ làm việc là bên tiêu thụ.

Header CSV mô tả hợp đồng: id, title và url. Đây là một schema ví dụ mang tính chuẩn, không phải một tập dữ liệu đã thu thập. Một nguồn không có bản ghi khớp sẽ khiến ví dụ dừng lại; nó không âm thầm gắn nhãn kết quả đó như một danh sách trống hợp lệ.

Khắc phục sự cố tại ranh giới thu thập

Các bản ghi bị thiếu cần được chẩn đoán dựa trên tài liệu đã thu thập và hợp đồng trích xuất. Một tệp CSV trống tự thân không cho biết nguyên nhân.

Triệu chứng Kiểm tra Hành động kỹ thuật có khả năng thực hiện
HTML tĩnh thiếu các bản ghi bắt buộc Phản hồi thô và trạng thái sẵn sàng của nguồn Chọn đường dẫn trình duyệt được phép
Trình duyệt hiển thị nội dung không liên quan Trang cuối cùng và trạng thái trang Sửa URL bắt đầu hoặc thao tác tương tác
Một số bản ghi thiếu ID hoặc tiêu đề Markup nguồn và các trường bắt buộc Cập nhật hoặc thu hẹp hợp đồng
Liên kết tương đối được xuất không chính xác URL gốc đã thu và thuộc tính liên kết Giải quyết liên kết dựa trên tài liệu chính xác
Không thể thiết lập kết nối từ xa Loại endpoint và phiên chuyên dụng Sửa cấu hình tài khoản và kết nối

Quy trình Java tập trung vào Jsoup hiện có bao quát cách tiếp cận thu thập theo hướng bộ phân tích cú pháp. Bài viết này bổ sung một hợp đồng dùng chung cho trình duyệt tĩnh, trình duyệt cục bộ và trình duyệt đám mây mà không thay thế trang đã xuất bản đó.

Kết luận

Web scraping bằng Java hoạt động tốt nhất khi thu thập và trích xuất là các quyết định tách biệt. Dùng Jsoup cho tài liệu bạn thực sự có, lấy HTML đã render khi nguồn yêu cầu, và xác thực cùng một hợp đồng bản ghi trước khi xuất.

Hoàn thiện chuỗi công cụ và các điều kiện tiên quyết cho phiên chuyên dụng, kiểm thử một trang đơn được phép, rồi thêm phân trang theo nguồn với phạm vi giới hạn.

Sẵn sàng kết nối trình thu thập Java với trình duyệt đám mây?

Xây dựng đường dẫn trình duyệt với Scrapeless và đánh giá nhu cầu tài nguyên của nó so với bảng giá hiện tại. Thảo luận các câu hỏi về quy trình Java trên Telegram.

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

H: Jsoup có thể thực thi JavaScript của một website không?

Jsoup phân tích HTML được cung cấp và không thực thi JavaScript của trang. Sử dụng đường dẫn thu thập qua trình duyệt khi các bản ghi cần thiết chỉ tồn tại sau khi render.

H: Web scraping bằng Java có được phép trên mọi trang công khai không?

Tính công khai không tạo thành sự cho phép cho mọi hành vi thu thập hoặc sử dụng. Xem lại điều khoản nguồn, quy tắc loại trừ robots, các yêu cầu áp dụng và thẩm quyền của dự án trước khi thu thập.

H: Quy trình Java này có yêu cầu proxy riêng không?

Client trình duyệt tĩnh hoặc cục bộ cần bất kỳ tuyến định được phép nào mà nguồn của nó yêu cầu. Đường dẫn đám mây sử dụng cấu hình Agent Browser đã cấp; cấu hình đường ra của nó thông qua thiết lập tài khoản hiện tại.

H: Trình thu thập nên làm gì với tài liệu bị thử thách hoặc bị từ chối truy cập?

Trình thu thập nên từ chối nội dung không phù hợp và lưu lại lý do thu thập. Kết nối trình duyệt đám mây không thay thế bước kiểm tra nội dung nguồn.

H: Tại sao cùng một selector có thể trả về không có dòng sau khi trang được cập nhật?

Nguồn có thể đã thay đổi markup, hành vi render hoặc danh tính trang. Kiểm tra lại những quan sát đó và URL cuối cùng trước khi thay đổi selector hoặc chấp nhận kết quả trống.

H: Một bản thử nghiệm Java nên dùng mức song song (concurrency) bao nhiêu?

Dùng một bản thử nghiệm có giới hạn với mức trần bảo thủ trên mỗi host, chẳng hạn ba worker theo chính sách ví dụ này. Quy tắc thu thập của nguồn và mức sử dụng tài nguyên quan sát được sẽ chi phối việc mở rộng.

H: Trình thu thập này có thể chạy mà không cần tác nhân AI hoặc song song với Selenium không?

Quy trình Java có thể chạy như mã xác định mà không có tác nhân AI. Dự án Selenium hiện có có thể giữ lớp thu thập qua trình duyệt và đưa HTML đã thu vào cùng hợp đồng xác thực và xuất.

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