Unlimited Plugins, WordPress themes, videos & courses! Unlimited asset downloads! From $16.50/m
Advertisement
  1. Code
  2. Ruby

Xây dựng Trình Thu thập Thông tin Trang web Đầu tiên Của bạn, Phần 1

by
Length:LongLanguages:

Vietnamese (Tiếng Việt) translation by Dai Phong (you can also view the original English article)

Trong lãnh địa của Ruby có hai gem được dùng để thu thập thông tin trang web trong vài năm qua: Nokogiri và Mechanize. Chúng ta dành một bài viết cho mỗi gem này trước khi chúng ta cài đặt chúng bằng một ví dụ thực tế.

Các chủ đề

  • Thu thập thông tin trang web là gì?
  • Quyền hạn
  • Vấn đề
  • Nokogiri
  • Việc trích xuất thông tin là gì?
  • Trang web
  • API
  • Điều hướng Trên các Nút

Thu thập thông tin trang web là gì?

Có những thuật ngữ gần gũi hơn so với thuật ngữ thu thập thông tin trang web hay màn hình. Thu thập và trích xuất dữ liệu web sẽ nói cho bạn biết ngay những gì đang xảy ra. Chúng ta có thể tự động trích xuất dữ liệu từ các trang web - và nó cũng không quá phức tạp.

Theo một cách nào đó, những công cụ này cho phép bạn bắt chước và tự động duyệt web như con người. Bạn viết một chương trình mà chỉ trích ra các loại dữ liệu mà bạn quan tâm. Nhắm chọn mẫu dữ liệu cụ thể dễ dàng như việc sử dụng các bộ chọn CSS.

Một vài năm trước đây, tôi đã đăng ký một số khóa học bằng video trực tuyến có chứa cả triệu video ngắn nhưng không có tùy chọn để tải chúng hàng loạt. Tôi đã phải tự mình duyệt qua tất cả các liên kết và tự mình làm công việc đáng sợ đó là "save as". Đó là kiểu thu thập thông tin trang web bằng con người - một điều mà chúng ta thường phải làm khi thiếu kiến ​​thức để tự động hóa loại công cụ đó. Bản thân các khóa học thì ổn, nhưng sau đó tôi đã không sử dụng các dịch vụ của họ nữa. Đơn giản là nó quá nhàm chán.

Ngày nay, tôi không quan tâm quá nhiều về cái UX như vậy. Một trình thu thập thông tin sẽ thực hiện công việc tải xuống cho tôi mà chỉ mất có một vài phút. Không có gì khó cả!

Hãy để tôi chia nhỏ từng bước trước khi chúng ta bắt đầu. Toàn bộ mọi thứ có thể được cô đặc thành một vài bước. Đầu tiên, chúng ta nạp trang web có chứa dữ liệu mong muốn. Sau đó, chúng ta tìm kiếm thông qua trang đó và xác định thông tin mà chúng ta muốn trích xuất.

Bước cuối cùng là nhắm các mẫu thông tin, cắt chúng ra nếu cần, và quyết định nơi lưu trữ và lưu trữ chúng như thế nào. HTML được viết tốt thường là chìa khoá để làm cho quá trình này trở nên dễ dàng và thú vị. Đối với các trích xuất sâu hơn, có thể sẽ rất khó khăn nếu bạn phải làm việc với markup có cấu trúc kém.

Còn các API thì sao? Câu hỏi rất hay. Nếu bạn có thể truy cập vào một dịch vụ với một API, thường thì không cần phải viết trình thu thập thông tin của riêng bạn. Cách làm này chủ yếu dành cho các trang web không cung cấp kiểu markup tiện lợi đó. Nếu không có một API, thường thì cách duy nhất là tự động hóa việc trích xuất thông tin từ các trang web.

Có thể bạn sẽ hỏi, việc thu thập này thật sự làm việc như thế nào? Không cần nghĩ sâu xa, câu trả lời ngắn gọn là bằng cách duyệt qua cấu trúc dữ liệu cây. Nokogiri xây dựng các cấu trúc dữ liệu này từ các tài liệu mà bạn cung cấp cho nó và cho phép bạn nhắm chọn các mẫu thông tin mà bạn muốn trích xuất. Ví dụ, CSS là một ngôn ngữ được viết cho việc duyệt cây, để tìm kiếm cấu trúc dữ liệu cây và chúng ta có thể tận dụng nó để trích xuất dữ liệu.

Có rất nhiều cách tiếp cận và giải pháp có thể được sử dụng. Lãnh địa Ruby có hai gem được sử dụng nhiều trong một vài năm gần đây. Nhiều người vẫn dựa vào Nokogiri và Mechanize cho các nhu cầu thu thập HTML. Cả hai đã được thử nghiệm và chứng minh chúng dễ sử dụng với khả năng cao. Chúng ta sẽ tìm hiểu cả hai. Nhưng trước tiên, tôi muốn dành một chút thời gian để định hình vấn đề mà chúng ta sẽ giải quyết vào cuối loạt bài giới thiệu ngắn này.

Quyền hạn

Trước khi bắt đầu thu thập, hãy đảm bảo là bạn được sự cho phép của các trang web mà bạn đang cố gắng truy cập để trích xuất dữ liệu. Ví dụ, nếu trang web có một API hoặc nguồn RSS, thì không chỉ dễ dàng để lấy nội dung mong muốn mà còn có thể là lựa chọn hợp pháp.

Không phải ai cũng sẽ đánh giá cao nếu bạn trích xuất trên các trang web của họ - đơn giản là vậy. Tự tìm hiểu trang web cụ thể mà bạn quan tâm, và đừng để gặp phải rắc rối. Ít khả năng gây ra các thiệt hại nghiêm trọng, nhưng nguy cơ gặp rắc rối vô tình không phải là không có.

Vấn đề

Tôi cần phải xây dựng một podcast mới. Tôi không muốn thiết kế như vậy, và tôi ghét cái cách xuất bản các bài viết mới. WYSIWYGs quái quỷ! Đôi điều về hoàn cảnh. Khoảng hai năm trước đây, tôi xây dựng phiên bản podcast đầu tiên của mình. Ý tưởng là để làm quen với Sinatra và xây dựng một cái gì đó siêu nhẹ. Tôi đã gặp phải một vài vấn đề không mong muốn vì tôi đã thực hiện khá nhiều thứ.

Chuyển từ Rails, đó chắc chắn là một kỳ học mà tôi đánh giá cao, nhưng tôi nhanh chóng hối tiếc vì không sử dụng một trang web tĩnh mà tôi có thể triển khai thông qua các trang GitHub. Xuất bản các tập mới và duy trì chúng một cách đơn giản là điều mà tôi đang tìm kiếm. Một lúc sau, tôi quyết định rằng tôi có một thứ lớn hơn để thử và tập trung vào việc xuất bản podcast mới.

Mùa hè vừa rồi, tôi bắt đầu làm việc nghiêm túc trên một trang web Middleman được lưu trữ thông qua các trang GitHub. Mặt khác, tôi muốn một cái gì đó mới mẻ. Một thiết kế mới, đơn giản, dùng Markdown để xuất bản các tập mới và không phải vật lộn với Heroku - tuyệt vời ông mặt trời! Vấn đề là tôi có có khoảng 139 tập cần phải được nhập và chuyển đổi trước khi làm việc với Middleman.

Đối với các bài viết, Middleman sử dụng các tập tin .markdown chứa dữ liệu được gọi là front-matter - về cơ bản thay thế cho cơ sở dữ liệu của tôi. Thực hiện việc chuyển đổi này bằng tay không phải là một lựa chọn hay đối với 139 tập. Đó là những gì cần phải tính toán. Tôi cần tìm ra một cách để phân tích HTML trên trang web cũ của tôi, thu thập các nội dung có liên quan và chuyển đổi nó sang các bài viết trên blog mà tôi sử dụng để xuất bản các podcast mới trên Middleman.

Do đó, trong ba bài viết tiếp theo, tôi sẽ giới thiệu với bạn các công cụ thường được sử dụng trong lãnh địa Ruby cho các tác vụ như thế này. Cuối cùng, chúng ta sẽ tìm hiểu giải pháp của tôi để cung cấp cho bạn một ví dụ thực tế.

Nokogiri

Ngay cả khi bạn hoàn toàn không rành về Ruby/Rails, khả năng cao là bạn đã nghe nói về gem nhỏ này. Cái tên ngắn gọn và dễ nhớ. Tôi không chắc rằng nhiều người biết rằng nokogiri là tiếng Nhật chỉ về "cái cưa".

Nó là một cái tên thích hợp khi bạn hiểu được công cụ đó làm gì. Người tạo ra gem này là người đáng yêu, Aaron Patterson. Nokogiri chuyển đổi các tài liệu XML và HTML thành một cấu trúc dữ liệu - chính xác hơn là một cấu trúc dữ liệu cây. Công cụ này chạy nhanh và đồng thời cung cấp một giao diện thú vị. Nhìn chung, đó là một thư viện rất tiềm năng để giải quyết các nhu cầu thu thập HTML của bạn.

Bạn có thể sử dụng Nokogiri không chỉ để phân tích HTML mà còn XML nữa. Nó cung cấp cho bạn các tùy chọn của cả ngôn ngữ XML và các giao diện CSS để duyệt qua các tài liệu mà bạn nạp vào. Ngôn ngữ XML, hay ngắn gọn là XPath, là một ngôn ngữ truy vấn.

Nó cho phép chúng ta chọn các nút từ các tài liệu XML. Các bộ chọn CSS khá quen thuộc ngay cả với người mới bắt đầu. Cũng giống như các phong cách mà bạn viết, các bộ chọn CSS giúp bạn dễ dàng nhắm chọn các phần cụ thể của các trang mà bạn muốn trích xuất. Bạn chỉ cần cho Nokogiri biết bạn muốn gì khi nhắm chọn một mục tiêu cụ thể.

Các trang

Những gì chúng ta luôn cần phải bắt đầu là tìm nạp trang thật sự mà chúng ta quan tâm. Chúng ta chỉ định loại tài liệu Nokogiri mà chúng ta muốn phân tích - ví dụ XML hoặc HTML:

some_scraper.rb

Nokogiri:XMLNokogiri:HTML có thể nhận các đối tượng IO hoặc các đối tượng String. Những gì xảy ra ở trên là rất đơn giản. Nó mở và tìm nạp trang được chỉ định bằng open-uri và sau đó nạp cấu trúc, XML hoặc HTML của nó vào một tài liệu Nokogiri mới. Những người mới không nên làm việc với XML quá sớm.

Do đó, tôi khuyên bạn hiện tại nên tập trung vào phân tích HTML. Tại sao lại là open-uri? Mô-đun này từ Thư viện Tiêu chuẩn của Ruby cho phép chúng ta lấy trang web mà không quá phiền phức. Bởi vì các đối tượng IO là khá phức tạp nên chúng ta có thể tận dụng open-uri.

API

Hãy thực hành điều này bằng một ví dụ nhỏ:

at_css

some_podcast_scraper.rb

Những gì chúng ta làm ở đây biểu diễn tất cả các bước thường liên quan đến việc thu thập trang web - chỉ là ở mức độ vi mô. Chúng ta quyết định URL nào mà chúng ta cần và trang web nào chúng ta cần tìm nạp và chúng ta nạp chúng vào trong một tài liệu Nokogiri mới. Sau đó, chúng ta mở trang đó và nhắm chọn một phần cụ thể.

Ở đây tôi chỉ muốn biết tiêu đề của tập mới nhất. Sử dụng phương thức at_css và một bộ chọn CSS chọn ra h2.post-title là tất cả những gì mà tôi cần để nhắm chọn mục tiêu cần trích xuất. Mặc dù vậy, với phương pháp này, chúng ta sẽ chỉ trích ra phần tử đơn lẻ này. Phương thức này cho chúng ta toàn bộ bộ chọn - phần lớn không phải là những gì chúng ta cần. Vì vậy, chúng ta chỉ trích xuất phần văn bản bên trong nút này thông qua phương thức text. Để so sánh, bạn có thể kiểm tra đầu ra cho cả tiêu đề và văn bản bên dưới.

Đầu ra

Mặc dù ví dụ này ít có ứng dụng thực tế, nhưng nó có tất cả các thành phần, tất cả các bước mà bạn cần để hiểu. Tôi thấy việc này cực kỳ đơn giản. Bởi vì có thể nó chưa được rõ ràng từ ví dụ này, nên tôi muốn chỉ ra công cụ này mạnh mẽ như thế nào. Hãy xem chúng ta có thể làm gì khác với một script Nokogiri.

Lưu ý!

Nếu bạn là người mới bắt đầu và không chắc chắn làm thế nào để nhắm chọn HTML cần thiết, thì tôi khuyên bạn nên tìm hiểu trên mạng cách phân tích nội dung của các trang web trong trình duyệt của bạn. Về cơ bản, ngày nay tất cả các trình duyệt chính đều làm cho quá trình này thật sự dễ dàng.

Trên Chrome bạn chỉ cần nhấp chuột phải vào một phần tử trên trang web và chọn tùy chọn inspect. Việc này sẽ mở ra một cửa sổ nhỏ ở dưới cùng của trình duyệt để hiển thị cho bạn một thứ giống như chế độ x-ray của DOM. Nó còn có nhiều tuỳ chọn khác, và tôi khuyên bạn nên dành một ít thời gian lên Google để tự học. Đó là một sự đầu tư khôn ngoan!

css

Phương thức css sẽ cho chúng ta không chỉ một phần tử duy nhất mà còn bất kỳ phần tử nào phù hợp với tiêu chí tìm kiếm trên trang. Khá gọn gàng và đơn giản!

some_scraper.rb

Đầu ra

Sự khác biệt nho nhỏ duy nhất trong ví dụ này là tôi lặp qua các tiêu đề trước tiên. Tôi cũng trích xuất văn bản bên trong bằng phương thức text. Nokogiri tự động dừng ở cuối của trang và không cố gắng mở các trang khác một cách tự động.

Giả sử chúng ta muốn có thêm một ít thông tin nữa, ví dụ ngày và phụ đề cho mỗi tập. Chúng ta chỉ cần mở rộng ví dụ ở trên. Ý tưởng tốt để làm việc này là làm từng bước một, bất kể điều gì. Lấy một mẫu code hoạt động và dần dần thêm các thứ.

some_scraper.rb

Đầu ra

Tại thời điểm này, chúng ta đã có được một số dữ liệu. Chúng ta có thể cấu trúc hoặc mổ xẻ nó theo cách mà chúng ta muốn. Ở trên sẽ chỉ ra những gì chúng ta có trong một định dạng dễ đọc. Tất nhiên chúng ta có thể đi sâu hơn vào từng cái bằng cách sử dụng các biểu thức chính quy cùng với phương thức text.

Chúng ta sẽ tìm hiểu kỹ hơn điều này khi chúng ta giải quyết vấn đề podcast thật sự. Nó sẽ không phải là một lớp học về regexp, nhưng bạn sẽ thấy thêm một số ví dụ thực tế - nhưng đừng lo lắng, không quá phức tạp đâu.

Thuộc tính

Đồng thời, những thứ có thể hữu ích ở giai đoạn này là trích xuất href cho từng tập. Không thể đơn giản hơn.

some_scraper.rb

Điểm quan trọng nhất cần lưu ý ở đây là [:href]podcast_url. Nếu bạn gắn thẻ vào [:], bạn có thể trích xuất một thuộc tính từ bộ chọn một cách đơn giản. Tôi hơi trừu tượng hoá một chút, nhưng bạn có thể thấy rõ hơn cách hoạt động của nó ở dưới đây.

Để có được một URL hoàn chỉnh và hữu ích, tôi đã lưu tên miền gốc trong một biến và cấu trúc URL đầy đủ cho mỗi tập.

Hãy xem qua đầu ra:

Đầu ra

Đơn giản, phải không? Bạn có thể thực hiện tương tự để trích xuất [:class] của một bộ chọn.

Nếu nút đó có nhiều hơn một lớp, bạn sẽ có được một danh sách của tất cả các lớp.

Điều hướng trên các nút

  • parent
  • children
  • previous_sibling
  • next_sibling

Chúng ta thường làm việc với các cấu trúc cây trong CSS hoặc thậm chí là jQuery. Sẽ rất khó khăn nếu Nokogiri không cung cấp một API tiện dụng để di chuyển bên trong những cái cây như vậy.

some_scraper.rb

Đầu ra

Như bạn có thể thấy, đây là một công cụ khá mạnh mẽ - đặc biệt khi bạn nhìn thấy những gì mà .parent có thể thu thập được chỉ trong một bước. Thay vì định nghĩa một bộ các nút một cách thủ công, thì bạn có thể thu thập toàn bộ chúng.

Bạn thậm chí có thể nối chúng liên tiếp để duyệt sâu hơn. Tất nhiên, bạn có thể làm cho nó phức tạp tuỳ bạn muốn, nhưng tôi muốn cảnh báo bạn nên giữ cho mọi thứ đơn giản. Nó có thể nhanh chóng trở nên khó sử dụng và khó hiểu. Hãy nhớ, "Giữ cho nó đơn giản!"

some_scraper.rb

Đầu ra

Phần Tóm lượt

Nokogiri không phải là một thư viện lớn, nhưng nó cung cấp rất nhiều thứ. Tôi khuyên bạn nên thực hành những gì mà bạn đã học được cho đến lúc này và mở rộng kiến ​​thức của bạn thông qua tài liệu hướng dẫn của nó khi bạn bí. Nhưng đừng để bản thân gặp khó khăn!

Bài giới thiệu ngắn gọn này chắc sẽ giúp bạn hiểu rõ hơn về những gì bạn có thể làm và cách nó hoạt động. Tôi hy vọng bạn sẽ tự mình khám phá nó thêm một chút và vui vẻ với nó. Rồi bạn sẽ thấy, đó là một công cụ rất mạnh mẽ.

Advertisement
Advertisement
Advertisement
Advertisement
Looking for something to help kick start your next project?
Envato Market has a range of items for sale to help get you started.