Computer >> Hướng Dẫn Máy Tính >  >> Lập Trình >> Ruby

Làm chủ Mechanize: Kỹ thuật Web Scraping nâng cao – Phần 2

Mục lục

  • Trang đơn vs. Phân trang
  • Mechanize
  • Agent
  • Page
  • Phương thức Nokogiri
  • Links
  • Click
  • Forms

Trang đơn vs. Phân trang

Cho đến nay chúng ta đã dành thời gian tìm hiểu cách thu thập dữ liệu từ một trang đơn lẻ bằng Nokogiri. Đó là nền tảng tốt để tiến xa hơn và học cách trích xuất nội dung từ nhiều trang.

Vấn đề chúng ta giải quyết là lấy nội dung từ hơn 140 tập podcast – lượng dữ liệu lớn hơn nhiều so với khả năng chứa của một trang web đơn lẻ. Chúng ta phải làm việc với phân trang và tìm ra cách theo dõi nội dung sâu hơn.

Đây chính là lúc Nokogiri dừng lại và gem Mechanize phát huy tác dụng.

Mechanize

Mechanize là công cụ mạnh mẽ khác cung cấp nhiều tính năng hữu ích. Nó cho phép tự động hóa tương tác với các trang web cần trích xuất dữ liệu. Về mặt này, nó nhắc nhớ một chút đến chức năng bạn có thể biết từ testing với Capybara.

Đừng hiểu lầm, chơi với Nokogiri trên một trang đơn lẻ đã tuyệt vời, nhưng cho các tác vụ trích xuất dữ liệu phức tạp hơn, chúng ta cần thêm "mã lực". Chúng ta có thể thu thập dữ liệu qua bao nhiêu trang tùy ý và tương tác với các phần tử của chúng – mô phỏng và tự động hóa hành vi con người. Rất mạnh mẽ!

Gem này cho phép bạn theo dõi liên kết, điền các trường form và gửi dữ liệu – kể cả xử lý cookie cũng nằm trong khả năng. Điều đó nghĩa là bạn cũng có thể mô phỏng đăng nhập của người dùng vào phiên riêng tư và lấy nội dung từ trang web chỉ bạn có quyền truy cập.

Bạn điền thông tin đăng nhập và chỉ dẫn Mechanize cách theo dõi. Vì có thể click liên kết và submit form, hầu như không có gì bạn không thể làm với công cụ này. Nó có mối quan hệ mật thiết với Nokogiri và phụ thuộc vào nó. Aaron Patterson lại là một trong những tác giả của gem tuyệt vời này.

Khởi tạo Mechanize Agent

Trước khi bắt đầu mechanize, chúng ta cần khởi tạo một Mechanize agent.

some_scraper.rb

Đối tượng agent này sẽ được dùng để lấy trang, tương tự như chúng ta đã làm với Nokogiri.

some_scraper.rb

Ở đây Mechanize agent lấy trang podcast và các cookie của nó.

Trích xuất nội dung trang

Bây giờ chúng ta có một trang sẵn sàng cho việc trích xuất. Trước khi làm điều đó, tôi khuyên nên nhìn "bên trong" bằng phương thức inspect.

some_scraper.rb

Đầu ra khá chi tiết. Hãy tự xem cấu trúc của đối tượng Mechanize::Page. Tại đây bạn có thể thấy tất cả các thuộc tính của trang đó.

Đối với tôi, đây là đối tượng rất tiện lợi để "cắt lát" dữ liệu bạn muốn trích xuất.

Đầu ra

Nếu muốn xem chính trang HTML, bạn có thể dùng phương thức body hoặc content.

some_scraper.rb

Đầu ra

Vì trang podcast này chỉ có số lượng yếu tố nhỏ, đây là Mechanize::Page trả về từ github.com – nó có nhiều loại nội dung hơn để tham khảo. Tôi nghĩ điều này quan trọng để nắm cảm giác.

Đầu ra github.com

Quay lại podcast, bạn cũng có thể xem các thứ như encoding, mã phản hồi HTTP, URI, hoặc header phản hồi.

some_scraper.rb

Đầu ra

Còn nhiều thứ hơn nữa nếu bạn muốn đào sâu hơn. Tôi dừng ở đây.

Phương thức Nokogiri

  • at
  • search

Mechanize sử dụng Nokogiri để thu thập dữ liệu từ các trang. Bạn có thể áp dụng những gì đã học về Nokogiri ở bài trước và dùng trên các trang Mechanize. Nghĩa là bạn dùng Mechanize để điều hướng trang và dùng phương thức Nokogiri cho nhu cầu scraping.

Ví dụ, nếu muốn tìm một đối tượng đơn lẻ, dùng at, trong khi search trả về tất cả đối tượng khớp với selector trên trang cụ thể. Tóm lại, các phương thức này hoạt động cả trên đối tượng tài liệu Nokogiri và đối tượng trang Mechanize.

some_scraper.rb

Đầu ra

Links

  • links
  • link_with
  • links_with

Chúng ta cũng có thể điều hướng toàn bộ trang web theo ý thích. Có lẽ phần quan trọng nhất của Mechanize là khả năng cho phép bạn "chơi" với các liên kết. Nếu không có tính năng này, bạn có thể chỉ dùng Nokogiri đơn thuần. Hãy xem Mechanize trả về gì khi yêu cầu các liên kết của một trang.

some_scraper.rb

Đầu ra

Trời ơi, hãy phân tích xem. Vì chúng ta chưa yêu cầu Mechanize nhìn nơi khác, nên nhận được một mảng liên kết chỉ từ trang đầu tiên đó. Mechanize duyệt trang theo thứ tự giảm dần và trả về danh sách liên kết từ trên xuống dưới. Tôi đã tạo một hình ảnh nhỏ với các mũi tên xanh trỏ đến các liên kết khác nhau trong đầu ra.

Bên cạnh đó, đây đã là kết quả cuối cùng của việc thiết kế lại podcast của tôi. Tôi nghĩ phiên bản này tốt hơn cho mục đích demo. Bạn cũng thấy trước cảm giác kết quả cuối cùng và tại sao tôi cần scraping trang Sinatra cũ.

Ảnh chụp màn hình

Làm chủ Mechanize: Kỹ thuật Web Scraping nâng cao – Phần 2 Làm chủ Mechanize: Kỹ thuật Web Scraping nâng cao – Phần 2 Làm chủ Mechanize: Kỹ thuật Web Scraping nâng cao – Phần 2

Như luôn, chúng ta cũng có thể trích xuất chỉ văn bản từ đó.

some_scraper.rb

Đầu ra

Lấy tất cả các liên kết một lúc có thể rất hữu ích hoặc đơn giản là rườm rà. May mắn thay, chúng ta có vài công cụ để tinh chỉnh những gì cần thiết.

some_scraper.rb

Đầu ra

Xong! Bây giờ chúng ta đang tiến triển! Chúng ta có thể zoom vào các liên kết cụ thể như vậy. Chúng ta có thể nhắm mục tiêu các liên kết khớp với tiêu chí nhất định – như văn bản của nó, ví dụ – với API đẹp đẽ hơn như links_with hoặc link_with. Ngoài ra, nếu có nhiều liên kết Focus, chúng ta có thể zoom vào một vị trí cụ thể trên trang bằng ngoặc vuông [].

some_scraper.rb

Nếu bạn không quan tâm đến văn bản liên kết mà muốn chính liên kết đó, bạn chỉ cần chỉ định href cụ thể để tìm liên kết đó. Mechanize không cản trở bạn. Thay vì text, bạn cung cấp cho phương thức href.

some_scraper.rb

Nếu bạn chỉ muốn tìm liên kết đầu tiên với văn bản mong muốn, cũng có thể dùng cú pháp này. Rất tiện lợi và dễ đọc hơn một chút.

some_scraper.rb

Làm sao để theo dõi liên kết đó và xem gì nằm sau Focus? Hãy click nó!

Click

some_scraper.rb

Điều này sẽ cho chúng ta một danh sách liên kết dài khác như trước. Thấy dễ dàng thế nào khi kết hợp .click.links. Mechanize click liên kết cho bạn và theo dõi trang đến đích mới. Vì chúng ta cũng yêu cầu danh sách liên kết, nên sẽ nhận được tất cả liên kết Mechanize tìm thấy trên trang mới đó.

Giả sử tôi có hai liên kết văn bản của cùng một phỏng vấn viên – một liên kết đến tags và một đến tập gần đây – và tôi muốn lấy liên kết từ cả hai trang.

some_scraper.rb

Điều này sẽ cho bạn danh sách liên kết cho cả hai trang. Bạn lặp qua từng liên kết của phỏng vấn viên, và Mechanize theo dõi liên kết được click và thu thập các liên kết nó tìm thấy trên trang mới cho bạn. Dưới đây là vài ví dụ để bạn so sánh các tổ hợp để bắt đầu.

some_scraper.rb

Forms

  • submit
  • field_with
  • checkbox_with
  • radiobuttons_with
  • file_uploads

Hãy xem xét forms!

some_scraper.rb

Đầu ra

Vì chúng ta dùng phương thức forms, nên nhận được một mảng – ngay cả khi chỉ có một form được trả về. Bây giờ biết form có tên "f", chúng ta có thể dùng phiên bản số ít form để tập trung vào form đó.

some_scraper.rb

Sử dụng form('f'), chúng ta chọn form cụ thể muốn làm việc. Kết quả là không nhận được mảng trả về.

Đầu ra

Chúng ta cũng có thể xác định tên trường nhập văn bản (q).

Chúng ta có thể nhắm mục tiêu nó bằng tên đó và đặt giá trị như thuộc tính Ruby. Chúng ta chỉ cần cung cấp giá trị mới. Bạn thấy từ ví dụ đầu ra trên rằng nó rỗng theo mặc định.

some_scraper.rb

Đầu ra

Như bạn quan sát, giá trị của trường văn bản đã thay thành New Google Search. Bây giờ chúng ta chỉ cần submit form và thu thập kết quả từ trang Google trả về. Không thể dễ hơn! Hãy tìm kiếm thứ khác!

some_scraper.rb

Ở đây tôi xác định header kết quả tìm kiếm bằng CSS selector h3.r, map text của nó, và pretty-print kết quả. Không quá khó, phải không? Đó là ví dụ dễ, nhưng hãy nghĩ về vô số khả năng bạn có!

Đầu ra

Mechanize có các trường nhập liệu khác nhau để bạn "chơi". Bạn thậm chí có thể upload file!

  • field_with
  • checkbox_with
  • radiobuttons_with
  • file_uploads

Bạn cũng có thể xác định radio button và checkbox theo tên và check chúng với – bạn đoán đúng – check.

some_scraper.rb

Thẻ option cho phép người dùng chọn một mục từ danh sách thả xuống. Lại nữa, chúng ta nhắm mục tiêu theo tên và chọn số thứ tự option mong muốn.

some_scraper.rb

Upload file hoạt động tương tự như nhập văn bản vào form bằng cách đặt giá trị như thuộc tính Ruby. Bạn xác định trường upload và chỉ định đường dẫn file (tên file) muốn chuyển. Nó nghe phức tạp hơn thực tế. Hãy xem!

some_scraper.rb

Lời kết

Thấy đấy, không có phép màu gì! Bây giờ bạn đã được trang bị tốt để tự khám phá. Chắc chắn còn nhiều thứ để học về Nokogiri và Mechanize, nhưng thay vì dành quá nhiều thời gian cho các khía cạnh không cần thiết, hãy tự thực hành và tra cứu tài liệu khi gặp vấn đề vượt quá phạm vi bài hướng dẫn người mới.

Tôi hy vọng bạn thấy gem này đơn giản đẹp đẽ và mạnh mẽ đến nhường nào. Như chúng ta biết từ văn hóa đại chúng, quyền lực này cũng mang lại trách nhiệm. Hãy sử dụng trong khuôn khổ pháp lý và khi không có API. Bạn có thể không thường xuyên dùng các công cụ này, nhưng chúng cực kỳ hữu ích khi bạn có nhu cầu scraping thực sự.

Như đã hứa, ở bài tiếp theo chúng ta sẽ xem ví dụ thực tế nơi tôi scraping dữ liệu từ trang podcast của mình. Tôi sẽ trích xuất từ trang Sinatra cũ và chuyển sang trang Middleman mới dùng file .markdown cho mỗi tập. Chúng ta sẽ lấy ngày, số tập, tên phỏng vấn viên, tiêu đề, phụ đề, v.v. Hẹn gặp lại!