https://dev.to/rachelsoderberg/create-a-simple-web-scraper-in-c-1l1m
Quét web là một kỹ năng có thể có ích trong một số tình huống, chủ yếu là khi bạn cần lấy một bộ dữ liệu cụ thể từ một trang web. Tôi tin rằng điều này được sử dụng thường xuyên nhất trong kỹ thuật và khoa học để lấy dữ liệu như số liệu thống kê hoặc bài viết với các từ khóa cụ thể. Đối với hướng dẫn này, tôi sẽ hướng dẫn bạn cách cạo một trang web cho phần sau - các bài viết với các từ khóa cụ thể.
Trước khi chúng tôi bắt đầu, tôi muốn giới thiệu web scraping và một số hạn chế của nó. Quét web còn được gọi là thu hoạch web hoặc trích xuất dữ liệu web và là phương pháp tự động trích xuất dữ liệu từ các trang web qua internet. Phương pháp phân tích cú pháp mà tôi sẽ dạy cho bạn hôm nay là phân tích cú pháp HTML, có nghĩa là trình quét web của chúng tôi sẽ xem xét nội dung HTML của một trang và trích xuất thông tin phù hợp với lớp chúng tôi muốn lấy thông tin từ (nếu điều này không thực hiện ý nghĩa, đừng lo lắng. Tôi sẽ đi vào chi tiết hơn sau!) Phương pháp quét web này bị hạn chế bởi thực tế là không phải tất cả các trang web lưu trữ tất cả thông tin của họ trong html - phần lớn những gì chúng ta thấy ngày nay là động và được xây dựng sau khi trang đã được tải Để xem thông tin đó, cần có trình thu thập dữ liệu web tinh vi hơn, thường là với trình tải web riêng của nó,
Tôi đã chọn xây dựng một trình quét web trong C # vì phần lớn các hướng dẫn đã xây dựng các trình dọn dẹp web của họ bằng Python. Mặc dù đó có thể là ngôn ngữ lý tưởng cho công việc, tôi muốn chứng minh với bản thân rằng nó có thể được thực hiện trong C #. Tôi cũng hy vọng sẽ giúp những người khác học cách xây dựng các trang web của riêng họ bằng cách cung cấp một trong số ít các hướng dẫn cạo web C # (tại thời điểm viết bài).
Xây dựng một dụng cụ quét web
Trang web mà chúng tôi sẽ tìm kiếm là Ocean Networks Canada , một trang web chuyên cung cấp thông tin về đại dương và hành tinh của chúng ta. Những người sử dụng dự án này để truy cập internet cho các bài báo và dữ liệu sẽ thấy rằng trang web này cung cấp một mô hình tương tự như nhiều trang web khác mà họ sẽ gặp.
- Khởi chạy Visual Studio và tạo Ứng dụng Windows Forms C # .NET mới.
- Thiết kế Biểu mẫu cơ bản bằng Nút để khởi động trình quét và Hộp văn bản có định dạng để in kết quả.
- Mở Trình quản lý gói NuGet của bạn bằng cách bấm chuột phải vào tên dự án của bạn trong Solution Explorer và chọn "Quản lý gói NuGet". Tìm kiếm "AngleSharp" và nhấp Cài đặt.
- Thêm một mảng các thuật ngữ truy vấn (đây phải là những từ bạn muốn bài viết của bạn có trong tiêu đề) và tạo một phương thức trong đó chúng tôi sẽ thiết lập tài liệu của chúng tôi để cạo. Mã của bạn sẽ trông như sau:
private string Title { get; set; } private string Url { get; set; } private string siteUrl = "https://www.oceannetworks.ca/news/stories"; public string[] QueryTerms { get; } = {"Ocean", "Nature", "Pollution"}; internal async void ScrapeWebsite() { CancellationTokenSource cancellationToken = new CancellationTokenSource(); HttpClient httpClient = new HttpClient(); HttpResponseMessage request = await httpClient.GetAsync(siteUrl); cancellationToken.Token.ThrowIfCancellationRequested(); Stream response = await request.Content.ReadAsStreamAsync(); cancellationToken.Token.ThrowIfCancellationRequested(); HtmlParser parser = new HtmlParser(); IHtmlDocument document = parser.ParseDocument(response); }CancellingTokenSource cung cấp mã thông báo nếu việc hủy bỏ được yêu cầu bởi một tác vụ hoặc chuỗi.
HttpClient cung cấp một lớp cơ sở để gửi các yêu cầu HTTP và nhận phản hồi HTTP từ tài nguyên được xác định bởi URI,
httpResponseMessage đại diện cho một thông điệp phản hồi HTTP và bao gồm mã trạng thái và dữ liệu.
HtmlParser và IHtmlDocument là các lớp AngleSharp cho phép bạn xây dựng và phân tích các tài liệu từ nội dung HTML của trang web. - Tạo một phương thức mới khác để nhận và hiển thị kết quả từ tài liệu AngleSharp của bạn. Ở đây chúng tôi sẽ phân tích tài liệu và truy xuất bất kỳ bài viết nào phù hợp với QueryTerms của chúng tôi. Điều này có thể khó khăn, vì không có hai trang web sử dụng cùng một quy ước đặt tên HTML - có thể cần một số thử nghiệm và lỗi để có được truy vấn LINQ "articleLink" chính xác:
private void GetScrapeResults(IHtmlDocument document) { IEnumerable<IElement> articleLink; foreach (var term in QueryTerms) { articleLink = document.All.Where(x => x.ClassName == "views-field views-field-nothing" && (x.ParentElement.InnerHtml.Contains(term) || x.ParentElement.InnerHtml.Contains(term.ToLower()))); } if (articleLink.Any()) { // Print Results: See Next Step } }Nếu bạn không chắc chắn điều gì đã xảy ra ở đây, tôi sẽ giải thích chi tiết hơn: Chúng tôi sẽ lặp qua từng QueryTerms (Đại dương, Thiên nhiên và Ô nhiễm) và phân tích thông qua tài liệu của chúng tôi để tìm tất cả các trường hợp trong đó ClassName là "lượt xem- trường xem-trường-không có gì "và trong đó ParentEuity.InnerHtml chứa thuật ngữ chúng tôi hiện đang truy vấn.Nếu bạn không quen với cách xem HTML của trang web, bạn có thể tìm thấy nó bằng cách điều hướng đến URL mong muốn của mình, nhấp chuột phải vào bất kỳ đâu trên trang và chọn "Xem nguồn trang". Một số trang có số lượng HTML nhỏ, số khác có hàng chục nghìn dòng. Bạn sẽ cần sàng lọc tất cả những điều này để tìm nơi lưu trữ các tiêu đề bài viết, sau đó xác định lớp chứa chúng. Một mẹo tôi sử dụng là tìm kiếm một phần của một trong các tiêu đề bài viết, sau đó di chuyển lên một vài dòng. - Bây giờ, nếu các thuật ngữ truy vấn của chúng tôi sinh lợi, chúng tôi sẽ có một danh sách một số bộ HTML bên trong đó là các tiêu đề bài viết và URL của chúng tôi. Tạo một phương thức mới để in kết quả của bạn vào Rich Textbox.
public void PrintResults(string term, IEnumerable<IElement> articleLink) { // Clean Up Results: See Next Step resultsTextbox.Text = $"{Title} - {Url}{Environment.NewLine}"; } - Nếu chúng ta in kết quả của mình, chúng sẽ trông giống như đánh dấu HTML với tất cả các thẻ, dấu ngoặc nhọn và các mục không thân thiện với con người khác. Chúng tôi cần chèn một phương thức sẽ dọn sạch kết quả của chúng tôi trước khi chúng tôi in chúng ra biểu mẫu và, giống như bước 5, đánh dấu sẽ thay đổi theo từng trang web.
private void CleanUpResults(IElement result) { string htmlResult = result.InnerHtml.ReplaceFirst(" <span class=\"field-content\"><div><a href=\"", "https://www.oceannetworks.ca"); htmlResult = htmlResult.ReplaceFirst("\">", "*"); htmlResult = htmlResult.ReplaceFirst("</a></div>\n<div class=\"article-title-top\">", "-"); htmlResult = htmlResult.ReplaceFirst("</div>\n<hr></span> ", ""); // Split Results: See Next Step }Vậy chuyện gì đã xảy ra ở đây? Chà, tôi đã kiểm tra InsideHtml của đối tượng kết quả đang đến để xem những thứ bổ sung cần phải được loại bỏ khỏi những gì tôi thực sự muốn hiển thị - Tiêu đề và URL. Làm việc từ trái sang phải, tôi chỉ cần thay thế từng đoạn nội dung html bằng một chuỗi trống hoặc "không có gì", sau đó cho đoạn giữa URL và tiêu đề tôi đã thay thế bằng "*" như một trình giữ chỗ để chia chuỗi sau này. Mỗi lần sử dụng Thay thế () này sẽ khác nhau trên mỗi trang web và thậm chí nó có thể không hoạt động hoàn hảo trên mỗi bài viết trên một trang web cụ thể. Bạn có thể tiếp tục thêm các thay thế mới hoặc bỏ qua chúng nếu chúng không phổ biến. - Tôi chắc chắn rằng bạn đã nhận thấy từ bước trước đó có một phương pháp cuối cùng để thêm trước khi chúng tôi có thể in một kết quả rõ ràng vào hộp văn bản của chúng tôi. Bây giờ chúng tôi đã dọn sạch chuỗi kết quả của mình, chúng tôi có thể sử dụng trình giữ chỗ "*" của mình để chia chuỗi thành hai chuỗi - Tiêu đề và URL.
private void SplitResults(string htmlResult) { string[] splitResults = htmlResult.Split('*'); Url = splitResults[0]; Title = splitResults[1]; } - Cuối cùng chúng ta có một kết quả sạch sẽ, thân thiện với con người! Nếu mọi việc suôn sẻ và các bài viết không thay đổi mạnh mẽ kể từ thời điểm viết, việc chạy mã của bạn sẽ cung cấp tập kết quả sau (và hơn thế nữa ... có rất nhiều!) Đã bị ứng dụng của bạn từ Ocean Networks loại bỏ :
Tôi hy vọng hướng dẫn này đã cung cấp cho bạn một cái nhìn sâu sắc về thế giới của quét web. Nếu có đủ sự quan tâm, tôi có thể tiếp tục loạt bài này và hướng dẫn bạn cách thiết lập ứng dụng của bạn để thực hiện một bản sửa lỗi mới vào các khoảng thời gian cụ thể và gửi cho bạn một email kiểu bản tin với kết quả có giá trị trong một ngày hoặc một tuần.
Nếu bạn muốn theo kịp tôi trên phương tiện truyền thông xã hội, hãy đến tìm tôi trên Twitter hoặc LinkedIn và nói xin chào!
Visual Studio: Tìm hiểu kịch bản web miễn phí trong 10 bước dễ dàng | Khai thác dữ liệu | HTMLAgilityPack | LINQ
https://dev.to/anjankant/visual-studio-learn-free-webscriping-in-easy-10-steps-data-mining-htmlagilitypack-linq-618

Một số lưu ý khi bình luận
Mọi bình luận sai nội quy sẽ bị xóa mà không cần báo trước (xem nội quy)
Bấm Thông báo cho tôi bên dưới khung bình luận để nhận thông báo khi admin trả lời
Để bình luận một đoạn code, hãy mã hóa code trước nhé