Mã HTML được phân tích cú pháp như thế nào?

Điều này phức tạp hơn một chút so với những gì bạn có thể mong đợi. Trước hết, bạn không muốn xử lý các trang HTML dưới dạng văn bản. Phân tích cú pháp văn bản HTML mà không dịch HTML trước thành cấu trúc dữ liệu chắc chắn sẽ nhạy cảm với các trang được tạo theo các cách khác nhau. Tuy nhiên, HTML được tìm thấy trong tự nhiên thường không hợp lệ. Tệ hơn nữa, trên thực tế, đôi khi nó là XHTML, trong khi các tài liệu tuyên bố là XHTML thường chứa các tính năng HTML, chẳng hạn như thiếu thẻ đóng, sử dụng chữ hoa, v.v.

Trình phân tích cú pháp SGML/SML của SWI-Prolog có thể tạo ra kết quả thường đủ tốt để cạo. Bộ tùy chọn tốt nhất phụ thuộc một chút vào bản chất của tài liệu. Các trang web hoặc mã hóa khác nhau đáng chú ý sử dụng XML nghiêm ngặt và phù hợp có thể yêu cầu các tùy chọn khác nhau. Dưới đây là một số mã để bắt đầu. Nó âm thầm bỏ qua tất cả các lỗi. Đây thường là những gì bạn muốn để cạo thực sự, nhưng việc xem các thông báo có thể hữu ích nếu bạn nhận được kết quả kỳ lạ

http_load_html[URL, DOM] :-
        setup_call_cleanup[http_open[URL, In,
                           [ timeout[60]
                           ]],
                           [   dtd[html, DTD],
                               load_structure[stream[In],
                                              DOM,
                                              [ dtd[DTD],
                                                dialect[sgml],
                                                shorttag[false],
                                                max_errors[-1],
                                                syntax_errors[quiet]
                                              ]]
                           ],
                           close[In]].

Lưu ý rằng việc sử dụng setup_call_cleanup/3 đảm bảo rằng kết nối đã mở cuối cùng sẽ bị đóng. Tuy nhiên, nó không ngăn được các ngoại lệ và lỗi là một phần bình thường trong quá trình xử lý tài liệu web. Thông thường, trình quét sẽ sử dụng cấu trúc điều khiển như bên dưới để xử lý URL và chỉ cần bỏ qua nó nếu không thể truy xuất dữ liệu từ URL. Lưu ý rằng chúng tôi cung cấp mã này dưới dạng mã ví dụ thay vì thư viện vì nhu cầu đối với một trình cạp thực tế có thể thay đổi rất nhiều. e. g. , việc từ bỏ có thể là không chấp nhận được và nếu có lỗi, bạn có thể đợi và thử lại hoặc quyết định của bạn có thể phụ thuộc vào lỗi được trả về, v.v.

Để trùng với việc ra mắt chức năng viết lại HTML phát trực tuyến cho Công nhân Cloudflare, chúng tôi đang mở nguồn công cụ viết lại Rust HTML [LOL HTML] được sử dụng để sao lưu API Trình ghi lại HTML của Công nhân. Chúng tôi cũng nghĩ đã đến lúc xem lại lịch sử viết lại HTML tại Cloudflare

Bài đăng trên blog đầu tiên sẽ giải thích những điều cơ bản về trình ghi lại HTML phát trực tuyến và các yêu cầu cụ thể của chúng tôi. Chúng tôi bắt đầu khoảng 8 năm trước bằng cách mô tả nhóm trình phân tích cú pháp 'đặc biệt' được tạo với chức năng cụ thể như viết lại địa chỉ e-mail hoặc thu nhỏ HTML. Đến năm 2016, máy trạng thái được xác định trong đặc tả HTML5 có thể được sử dụng để xây dựng một trình ghi lại có thể cắm HTML tuân thủ thông số kỹ thuật duy nhất, để thay thế bộ sưu tập trình phân tích cú pháp hiện có. Mã nguồn cho trình ghi lại này hiện đã được công khai và có sẵn tại đây. https. //github. com/cloudflare/lazyhtml

Bài đăng trên blog thứ hai sẽ mô tả lần lặp lại tiếp theo của trình viết lại. Với sự ra mắt của nền tảng điện toán biên Cloudflare Worker, chúng tôi nhận ra rằng các nhà phát triển muốn có khả năng viết lại HTML tương tự với API JavaScript. Bài đăng mô tả những suy nghĩ đằng sau trình ghi lại HTML phát trực tuyến có độ trễ thấp với API dựa trên bộ chọn CSS. Chúng tôi đã mở nguồn thư viện Rust vì nó cũng có thể được sử dụng như một thư viện viết lại/phân tích cú pháp HTML độc lập

Trình viết lại HTML phát trực tuyến là gì?

Trình ghi lại HTML phát trực tuyến lấy đầu vào chuỗi HTML hoặc luồng byte, phân tích cú pháp đó thành mã thông báo hoặc bất kỳ biểu diễn trung gian có cấu trúc [IR] nào khác - chẳng hạn như Cây cú pháp trừu tượng [AST]. Sau đó, nó thực hiện các chuyển đổi trên mã thông báo trước khi chuyển đổi trở lại HTML. Điều này cung cấp khả năng sửa đổi, trích xuất hoặc thêm vào tài liệu HTML hiện có khi các byte đang được xử lý. So sánh điều này với trình phân tích cú pháp cây HTML tiêu chuẩn cần truy xuất toàn bộ tệp để tạo cây DOM đầy đủ. Trình ghi lại dựa trên cây sẽ mất nhiều thời gian hơn để phân phối các byte được xử lý đầu tiên và yêu cầu nhiều bộ nhớ hơn

trình viết lại HTML

Ví dụ; . Bạn sẽ nhanh chóng gặp vấn đề về tài nguyên [hình ảnh, tập lệnh, video] được cung cấp qua HTTP. 'Nội dung hỗn hợp' này mở ra một lỗ hổng bảo mật và các trình duyệt sẽ cảnh báo hoặc chặn các tài nguyên này. Có thể khó hoặc thậm chí không thể cập nhật mọi liên kết trên mọi trang của trang web. Với trình ghi lại HTML phát trực tuyến, bạn có thể chọn thuộc tính URI của bất kỳ thẻ HTML nào và thay đổi bất kỳ liên kết HTTP nào thành HTTPS. Chúng tôi đã xây dựng tính năng viết lại HTTPS tự động này vào năm 2016 để giải quyết các vấn đề về nội dung hỗn hợp cho khách hàng của chúng tôi

Người đọc có thể đã tự hỏi. “Đây không phải là một vấn đề đã được giải quyết sao, không có nhiều trình duyệt nguồn mở được sử dụng rộng rãi với trình phân tích cú pháp HTML có thể được sử dụng cho mục đích này sao?”. Thực tế là việc viết mã để chạy trong hơn 190 PoP trên toàn thế giới với yêu cầu nghiêm ngặt về độ trễ thấp đã biến những vấn đề tưởng chừng như tầm thường thành những thách thức kỹ thuật phức tạp

Các bài đăng trên blog sau đây sẽ trình bày chi tiết hành trình bắt đầu bằng một ý tưởng đơn giản là tìm địa chỉ email trong trang HTML dẫn đến việc xây dựng trình phân tích cú pháp HTML gần như tuân thủ thông số kỹ thuật và sau đó là bộ chọn CSS phù hợp với Máy ảo. Chúng tôi đã học được rất nhiều trên hành trình này. Tôi hy vọng bạn tìm thấy một số điều này là thú vị như chúng tôi đã làm

Viết lại ở rìa

Khi viết lại nội dung thông qua Cloudflare, chúng tôi không muốn ảnh hưởng đến hiệu suất trang web. Sự cân bằng trong việc thiết kế trình ghi lại HTML trực tuyến là để giảm thiểu việc tạm dừng trong luồng byte phản hồi bằng cách giữ càng ít thông tin càng tốt trong khi vẫn giữ được khả năng ghi lại các mã thông báo phù hợp

Sự khác biệt về yêu cầu so với trình phân tích cú pháp HTML được sử dụng trong trình duyệt bao gồm

Độ trễ đầu ra

Đối với các trình duyệt, Mô hình đối tượng tài liệu [DOM] là sản phẩm cuối cùng của quá trình phân tích cú pháp nhưng trong trường hợp của chúng tôi, chúng tôi phải phân tích cú pháp, viết lại và tuần tự hóa trở lại HTML. Trong trường hợp proxy ngược của Cloudflare, bất kỳ quá trình xử lý nội dung nào trên máy chủ biên đều dẫn đến độ trễ giữa máy chủ và nhãn cầu. Mong muốn giảm thiểu tác động độ trễ của việc xử lý HTML, bao gồm phân tích cú pháp, viết lại và tuần tự hóa trở lại HTML. Trong tất cả các giai đoạn này, chúng tôi muốn nhanh nhất có thể để giảm thiểu độ trễ

Thông lượng trình phân tích cú pháp

Giả sử rằng thông thường các trình duyệt hiếm khi cần xử lý các trang HTML có kích thước lớn hơn 1Mb và thời gian tải trang trung bình tốt nhất là khoảng 3 giây. Phân tích cú pháp HTML không phải là nút cổ chai chính của quá trình tải trang vì trình duyệt sẽ bị chặn khi chạy tập lệnh và tải các tài nguyên quan trọng khác. Chúng tôi có thể ước tính sơ bộ rằng ~3Mb/giây là thông lượng có thể chấp nhận được đối với trình phân tích cú pháp HTML của trình duyệt. Tại Cloudflare, chúng tôi có hàng trăm megabyte lưu lượng truy cập trên mỗi CPU, vì vậy chúng tôi cần một trình phân tích cú pháp nhanh hơn theo thứ tự cường độ

Giới hạn bộ nhớ

Như hầu hết người dùng phải nhận ra, các trình duyệt có khả năng tiêu thụ bộ nhớ. Ví dụ: đánh dấu HTML đơn giản này khi được mở trong trình duyệt sẽ tiêu tốn một lượng đáng kể bộ nhớ hệ thống của bạn trước khi tạm dừng tab trình duyệt [và tất cả bộ nhớ này sẽ được trình phân tích cú pháp sử dụng]


   document.write['start_tag;
    if [tag->type == LHTML_TAG_A] { // check whether tag is of type 
      const size_t n_attrs = tag->attributes.count;
      const lhtml_attribute_t *attrs = tag->attributes.items;
      for [size_t i = 0; i < n_attrs; i++] { // iterate over attributes
        const lhtml_attribute_t *attr = &attrs[i];
        if [lhtml_name_equals[attr->name, "href"]] { // match the attribute name
          attr->value = REPLACEMENT; // set the attribute value
        }
      }
    }
  }
  lhtml_emit[token, extra]; // pass transformed token[s] to next handler[s]
}

Vì vậy, nó là chính xác và nó nhanh như thế nào?

Nó tuân thủ HTML5 khi được thử nghiệm với các bộ thử nghiệm chính thức. Là một phần của công việc, một số đóng góp đã được gửi đến chính đặc điểm kỹ thuật để làm rõ/đơn giản hóa ngôn ngữ đặc tả

Không giống như [các] trình phân tích cú pháp trước đó, nó không cứu được bất kỳ tài liệu nào trong số 2.382.625 tài liệu từ Lưu trữ HTTP, mặc dù 0. 2% tài liệu vượt quá giới hạn bộ đệm dự kiến ​​vì trên thực tế chúng là JavaScript hoặc RSS hoặc các loại nội dung khác được phân phát không chính xác với Loại nội dung. văn bản/html và vì mọi thứ đều là HTML5 hợp lệ, trình phân tích cú pháp đã cố phân tích cú pháp e. g. a

Chủ Đề