Làm thế nào để bạn phân tích cú pháp một trang html?

Phân tích cú pháp HTML là một phần quan trọng của việc quét web, vì nó cho phép chuyển đổi nội dung trang web thành dữ liệu có cấu trúc và có ý nghĩa. Tuy nhiên, vì HTML là một định dạng có cấu trúc cây, nên nó yêu cầu một công cụ thích hợp để phân tích cú pháp, vì nó không thể duyệt qua thuộc tính bằng Regex

Bài viết này sẽ tiết lộ phổ biến nhất. NET để phân tích cú pháp HTML với các phần mạnh và yếu của chúng

Thư viện phân tích cú pháp HTML

Hãy xem xét nhanh các thư viện với giấy phép, sắc thái, v.v.

HtmlGói Agility

HtmlAgilityPack là một trong những thư viện phân tích cú pháp HTML nổi tiếng nhất (nếu không phải là nhất) trong. thế giới mạng. Kết quả là, nhiều bài báo đã được viết về nó

Tóm lại, nó là một thư viện nhanh, tương đối tiện dụng để làm việc với HTML (giả sử các truy vấn XPath đơn giản)

Giấy phép MIT

Thư viện phân tích cú pháp này sẽ thuận tiện nếu tác vụ là điển hình và được mô tả tốt bằng biểu thức XPath. Ví dụ: để lấy tất cả các liên kết từ một trang, chúng tôi cần rất ít mã

public IEnumerable<string> HtmlAgilityPackParse()
{
HtmlDocument htmlSnippet = new HtmlDocument();
htmlSnippet.LoadHtml(Html);

List<string> hrefTags = new List<string>();

foreach (HtmlNode link in htmlSnippet.DocumentNode.SelectNodes("//a[@href]"))
{
HtmlAttribute att = link.Attributes["href"];
hrefTags.Add(att.Value);
}

return hrefTags;
}

Tuy nhiên, việc sử dụng các lớp CSS không thuận tiện cho thư viện này và yêu cầu tạo các biểu thức phức tạp hơn

public IEnumerable<string> HtmlAgilityPackParse()
{
HtmlDocument hap = new HtmlDocument();
hap.LoadHtml(html);
HtmlNodeCollection nodes = hap
.DocumentNode
.SelectNodes("//h3[contains(concat(' ', @class, ' '), ' r ')]/a");

List<string> hrefTags = new List<string>();

if (nodes != null)
{
foreach (HtmlNode node in nodes)
{
hrefTags.Add(node.GetAttributeValue("href", null));
}
}

return hrefTags;
}

Trong số những điều kỳ lạ được quan sát - một API cụ thể, đôi khi khó hiểu và khó hiểu. Tuy nhiên, thực tế là thư viện không còn bị bỏ hoang đã làm tăng thêm sự nhiệt tình và khiến nó trở thành một giải pháp thay thế thực sự cho AngleSharp

GócSắc Nét

AngleSharp được viết từ đầu bằng C#

API dựa trên đặc tả JavaScript HTML DOM chính thức. Có những điều kỳ quặc ở một số nơi không bình thường đối với. NET (e. g. , việc truy cập một chỉ mục không hợp lệ trong bộ sưu tập sẽ trả về giá trị rỗng thay vì đưa ra một ngoại lệ;

Giấy phép MIT

Mã thư viện sạch sẽ, gọn gàng và thân thiện với người dùng

Ví dụ: trích xuất các liên kết từ trang hầu như không khác với các lựa chọn thay thế Javascript và Python

public IEnumerable<string> AngleSharpParse()
{
List<string> hrefTags = new List<string>();

var parser = new HtmlParser();
var document = parser.Parse(Html);
foreach (IElement element in document.QuerySelectorAll("a"))
{
hrefTags.Add(element.GetAttribute("href"));
}

return hrefTags;
}

CsQuery

CsQuery là một cổng jQuery cho. NET. Nó triển khai tất cả các bộ chọn CSS2 và CSS3, tất cả các phương thức thao tác DOM của jQuery và một số phương thức tiện ích

Đó là một trong những trình phân tích cú pháp HTML hiện đại dành cho. NET. Thư viện được dựa trên trình xác nhận. nu cho Java, đến lượt nó là cổng của trình phân tích cú pháp từ công cụ Gecko (Firefox)

giấy phép MIT

Thật không may, dự án bị bỏ rơi bởi tác giả. Đề xuất thay thế cho nó là AngleSharp

Mã nhận liên kết từ một trang trông đẹp mắt và quen thuộc với bất kỳ ai đã sử dụng jQuery

public IEnumerable<string> CsQueryParse()
{
List<string> hrefTags = new List<string>();

CQ cq = CQ.Create(Html);
foreach (IDomObject obj in cq.Find("a"))
{
hrefTags.Add(obj.GetAttribute("href"));
}

return hrefTags;
}

người xì hơi

Fizzler là một tiện ích bổ sung cho HtmlAgilityPack (việc triển khai của Fizzler dựa trên HtmlAgilityPack), cho phép bạn sử dụng bộ chọn CSS

giấy phép GNU GPL

Hãy khám phá xem Fizzler giải quyết vấn đề gì bằng cách sử dụng mẫu từ tài liệu

// Load the document using HTMLAgilityPack as normal
var html = new HtmlDocument();
html.LoadHtml(@"




Fizzler


CSS Selector Engine



");

// Fizzler for HtmlAgilityPack is implemented as the
// QuerySelectorAll extension method on HtmlNode

var document = html.DocumentNode;

// yields: [

Fizzler

]

document.QuerySelectorAll(".content");

// yields: [

Fizzler

,

CSS Selector Engine

]

document.QuerySelectorAll("p");

// yields empty sequence
document.QuerySelectorAll("body>p");

// yields [

Fizzler

,

CSS Selector Engine

]

document.QuerySelectorAll("body p");

// yields [

Fizzler

]

document.QuerySelectorAll("p:first-child");

Nó có tốc độ gần bằng với HtmlAgilityPack, nhưng thuận tiện hơn vì có bộ chọn CSS

biểu thức chính quy

Regex đã cũ và không phải là cách tiếp cận tốt để phân tích cú pháp HTML. Tuy nhiên, cách này cho phép bạn thực hiện tác vụ nhanh hơn nhiều so với việc sử dụng các thư viện xây dựng cây DOM

Nếu nói đến các biểu thức chính quy, bạn nên hiểu rằng bạn không thể xây dựng một giải pháp phổ quát và hoàn toàn đáng tin cậy trên chúng. Tuy nhiên, nếu bạn muốn phân tích cú pháp một trang web cụ thể, vấn đề này có thể không quá nghiêm trọng

Thông tin giấy phép

Mã nhận liên kết từ trang trông vẫn rõ ràng

public IEnumerable<string> Regex()
{
List<string> hrefTags = new List<string>();

Regex reHref = new Regex(@"(?inx)
]*
href \s* = \s*
(? ['""] )
(? [^""]+ )
\k
[^>]* >");

foreach (Match match in reHref.Matches(Html))
{
hrefTags.Add(match.Groups["url"].ToString());
}

return hrefTags;
}

Nếu bạn đột nhiên muốn phân tích cú pháp các bảng bằng Regex và thậm chí ở định dạng ưa thích, vui lòng xem trước

điểm chuẩn

Xét cho cùng, tốc độ của trình phân tích cú pháp là một trong những thuộc tính quan trọng nhất. Tốc độ phân tích cú pháp HTML xác định bạn sẽ mất bao lâu để hoàn thành một tác vụ nhất định

Để đo hiệu suất của trình phân tích cú pháp, tôi đã sử dụng thư viện BenchmarkDotNet từ DreamWalker

Các phép đo được thực hiện trên CPU Intel® Core(TM) i9-9880H @ 2. 30GHz, nhưng kinh nghiệm cho chúng tôi biết rằng thời gian tương đối sẽ giống nhau trên bất kỳ cấu hình nào khác

Ghi chú

Regex là một công cụ tuyệt vời, nhưng làm việc với HTML không phải là nhiệm vụ của việc sử dụng nó. Tuy nhiên, như một thử nghiệm, tôi đã thử triển khai một phiên bản mã làm việc tối thiểu. Mặc dù nó hoạt động hoàn hảo, nhưng lượng thời gian tôi dành cho việc lập trình cho thấy rằng tôi chắc chắn sẽ không làm điều đó nữa

Chà, chúng ta hãy xem điểm chuẩn

trích xuất URL từ các liên kết trang

Đối với tôi, nhiệm vụ này dường như là cơ bản đối với tất cả các trình phân tích cú pháp - thường xuyên hơn không, đây là cách bắt đầu phần giới thiệu về thế giới của các trình phân tích cú pháp (đôi khi cả Regex)

Như một ví dụ cạo, tôi đã sử dụng trang chính của ScrapingAnt

Mã điểm chuẩn có thể được tìm thấy trên Github và có một bảng với các kết quả bên dưới

MethodMeanErrorMedianHtmlAgilityPack3. 653 ms0. 087 ms3. 579 msAngleSharp5. 864 ms0. 091 ms5. 853 msCsQuery14. 269 ​​ms0. 284 ms13. 931 msFizzler4. 147 ms0. 081 ms4. 105 msRegex0. 547 ms0. 010 ms0. 543. 0 mili giây

Nói chung, Regex được cho là nhanh nhất nhưng không phải là thoải mái nhất. HtmlAgilityPack và Fizzler cho thấy thời gian xử lý xấp xỉ như nhau, nhỉnh hơn AngleSharp một chút. Thật không may, CsQuery đã bị tụt lại phía sau một cách vô vọng

Khai thác dữ liệu từ bảng HTML

Nhiệm vụ này rất phổ biến đối với một số khách truy cập vào trang web của chúng tôi, vì chúng tôi cung cấp danh sách các proxy miễn phí được cập nhật liên tục để quét web trong phạm vi công cộng

Mã của tất cả các thư viện đều giống nhau, điểm khác biệt duy nhất là API

Tuy nhiên, có hai điều đáng nói. đầu tiên, AngleSharp có các giao diện chuyên biệt, giúp thực hiện công việc dễ dàng hơn. Thứ hai, Regex hoàn toàn không phù hợp với nhiệm vụ này

MethodMeanErrorMedianHtmlAgilityPack3. 323 ms0. 0947 ms3. 317 msAngleSharp3. 920 ms0. 0557 ms3. 929 msCsQuery8. 475 ms0. 2227 ms8. 400 msFizzler3. 217 ms0. 0637 ms3. 205 msRegex9. 636 ms0. 1904 ms9. 456 mili giây

Như trong ví dụ trước, HtmlAgilityPack, AngleSharp và Fizzler đã hiển thị cùng thời điểm và rất tốt

Thật ngạc nhiên, CsQuery và Regex cho thấy thời gian xử lý tệ như nhau. Mặc dù mọi thứ đều rõ ràng với CsQuery - nó chỉ chậm, nhưng với Regex thì không rõ ràng lắm - rất có thể vấn đề có thể được giải quyết theo cách tối ưu hơn

Phần kết luận

Các kết luận, có lẽ, mọi người đã làm cho chính mình. Tuy nhiên, tôi muốn nói thêm rằng sự lựa chọn tốt nhất hiện tại sẽ là AngleSharp, vì nó đang được phát triển tích cực, có API trực quan và hiển thị thời gian xử lý tốt

Việc chuyển sang AngleSharp từ HtmlAgilityPack có hợp lý không?

Làm cách nào để phân tích tệp HTML trong JavaScript?

Chúng tôi có thể phân tích chuỗi HTML bằng cách đặt chuỗi thành InternalHTML hoặc sử dụng DOMParser . Chúng ta có thể chuyển đổi một chuỗi thành float bằng parseFloat. Để đọc nội dung của tệp khi nó được chọn, chúng ta có thể sử dụng hàm tạo FileReader.

Trình phân tích cú pháp HTML tốt nhất là gì?

Trình phân tích cú pháp HTML/XML nhanh và ổn định. htmlparser2 là trình phân tích cú pháp HTML nhanh nhất và sử dụng một số lối tắt để đến đó. Nếu bạn cần tuân thủ thông số kỹ thuật HTML nghiêm ngặt, hãy xem parse5

Làm cách nào để phân tích cú pháp HTML bằng Python?

Ví dụ .
từ html. trình phân tích cú pháp nhập HTMLParser
Trình phân tích cú pháp lớp (HTMLParser)
# phương pháp nối thêm thẻ bắt đầu vào danh sách start_tags
def handle_starttag(bản thân, thẻ, attrs)
start_tags toàn cầu
start_tags. nối thêm (thẻ)
# phương pháp nối thêm thẻ kết thúc vào danh sách end_tags
def handle_endtag(bản thân, thẻ)

Điều gì phân tích các trang như một trình duyệt web?

Việc phân tích cú pháp sẽ được thực hiện bởi công cụ trình duyệt (đừng nhầm với công cụ Javascript của trình duyệt). Công cụ trình duyệt là thành phần cốt lõi của mọi trình duyệt chính và vai trò chính của nó là kết hợp cấu trúc (HTML) và kiểu dáng (CSS) để nó có thể vẽ trang web trên màn hình của chúng ta.