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

Xây dựng Web Scraper đầu tiên: Hướng dẫn cho người mới bắt đầu – Phần 1

Mục lục

  • Web Scraping là gì?
  • Quyền truy cập
  • Vấn đề cần giải quyết
  • Nokogiri
  • Trích xuất?
  • Pages
  • API
  • Điều hướng Node

Web Scraping là gì?

Có nhiều thuật ngữ hoa mỹ hơn "web scraping" hay "screen scraping". "Web harvesting" (thu hoạch web) và "web data extraction" (trích xuất dữ liệu web) nói lên ngay bản chất vấn đề. Chúng ta có thể tự động hóa việc trích xuất dữ liệu từ các trang web – và nó không phức tạp như bạn nghĩ.

Về mặt nào đó, các công cụ này cho phép bạn mô phỏng và tự động hóa việc duyệt web của con người. Bạn viết chương trình chỉ trích xuất loại dữ liệu bạn quan tâm. Nhắm mục tiêu dữ liệu cụ thể gần như dễ dàng như dùng CSS selector.

Vài năm trước, tôi đăng ký khóa học video trực tuyến có hàng triệu video ngắn nhưng không có tùy chọn tải xuống hàng loạt. Tôi phải đi qua từng link và làm thủ công "save as" khổ sở. Đó là một dạng "web scraping bằng tay" – thứ chúng ta thường phải làm khi thiếu kiến thức tự động hóa. Khóa học ổn, nhưng sau đó tôi không dùng dịch vụ của họ nữa. Quá mệt mỏi!

Hôm nay, tôi không quan tâm nhiều đến UX khiến não bộ tan chảy như vậy. Một scraper tải xuống cho tôi chỉ mất vài phút để viết. Không vấn đề gì!

Để tôi phân tích nhanh trước khi bắt đầu. Toàn bộ quy trình có thể rút gọn thành vài bước. Trước tiên, chúng ta tải trang web chứa dữ liệu mong muốn. Sau đó, tìm kiếm qua trang đó và xác định thông tin cần trích xuất.

Bước cuối là nhắm mục tiêu các mảnh dữ liệu đó, cắt lát nếu cần, và quyết định lưu trữ như thế nào và ở đâu. HTML viết tốt thường là chìa khóa khiến quá trình này dễ dàng và thú vị. Đối với trích xuất phức tạp hơn, nó có thể đau đầu nếu phải xử lý markup cấu trúc kém.

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

Bạn có thể hỏi, scraping thực sự hoạt động như thế nào? Không đi sâu vào chi tiết, câu trả lời ngắn gọn: bằng cách duyệt 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ừ tài liệu bạn cung cấp và cho phép bạn nhắm mục tiêu các phần quan tâm để trích xuất. Ví dụ, CSS là ngôn ngữ 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ó cho trích xuất dữ liệu.

Có nhiều cách tiếp cận và giải pháp để thử. Rubyland có hai gem chiếm据 spotlight vài năm nay. Nhiều người vẫn tin dùng Nokogiri và Mechanize cho nhu cầu scraping HTML. Cả hai đã được kiểm chứng, dễ dùng và khả năng cao. Chúng ta sẽ xem cả hai. Nhưng trước đó, tôi muốn dành chút thời gian nói về vấn đề chúng ta sẽ giải quyết ở cuối serie giới thiệu ngắn này.

Quyền truy cập

Trước khi bắt đầu scraping, hãy chắc chắn bạn có quyền truy cập của các trang web bạn muốn lấy dữ liệu. Nếu trang có API hoặc RSS feed, ví dụ, nó không chỉ dễ dàng hơn để lấy nội dung mong muốn, mà có thể là lựa chọn hợp pháp.

Không phải ai cũng thích nếu bạn scraping lớn trên trang của họ – điều dễ hiểu. Hãy tự trang bị kiến thức về trang web cụ thể bạn quan tâm, và đừng tự rước rắc. Xác suất gây thiệt hại nghiêm trọng thấp, nhưng mạo hiểm không biết là không nên.

Vấn đề cần giải quyết

Tôi cần xây dựng podcast mới. Thiết kế chưa như ý, và tôi ghét cách đăng bài mới. Chết tiệt WYSIWYG! Chút bối cảnh: Khoảng 2 năm trước, tôi xây dựng phiên bản đầu tiên của podcast. Ý tưởng là chơi với Sinatra và xây dựng thứ gì đó siêu nhẹ. Tôi gặp vài vấn đề bất ngờ vì tự làm hầu như mọi thứ.

Đến từ Rails, chắc chắn là hành trình học hỏi quý giá mà tôi trân trọng, nhưng tôi nhanh chóng hối hận vì không dùng static site có thể deploy qua GitHub Pages. Việc deploy tập mới và duy trì thiếu sự đơn giản tôi tìm kiếm. Một thời gian, tôi quyết định có "cá lớn hơn để chiên" và tập trung sản xuất nội dung podcast.

Mùa hè vừa rồi, tôi bắt đầu nghiêm túc và làm việc trên trang Middleman host qua GitHub Pages. Cho mùa 2, tôi muốn thứ mới mẻ. Thiết kế đơn giản hóa, Markdown để đăng tập mới, và không còn "đấu súng" với Heroku – thiên đường! Vấn đề là tôi có 139 tập cũ cần import và chuyển đổi trước để làm việc với Middleman.

Đối với bài viết, Middleman dùng file .markdown có frontmatter cho dữ liệu – thay thế database cơ bản. Làm thủ công với 139 tập không phải lựa chọn. Đó là lúc tính toán phát huy tác dụng. Tôi cần cách parse HTML trang cũ, scraping nội dung liên quan, và chuyển sang bài viết blog để đăng podcast trên Middleman.

Do đó, qua 3 bài tới, tôi sẽ giới thiệu công cụ thường dùng trong Rubyland cho tác vụ này. Cuối cùng, chúng ta sẽ xem giải pháp thực tế của tôi.

Nokogiri

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

Tên gọi phù hợp khi bạn hiểu công cụ này làm gì. Tác giả gem là Tenderlove, Aaron Patterson. Nokogiri chuyển đổi tài liệu XML và HTML thành cấu trúc dữ liệu – chính xác hơn là cấu trúc dữ liệu cây. Công cụ nhanh và cung cấp interface đẹp. Tổng thể, đây là thư viện mạnh mẽ giải quyết đa số nhu cầu scraping HTML của bạn.

Bạn có thể dùng Nokogiri không chỉ để parse HTML; XML cũng được. Nó cung cấp cả XPath (XML Path Language) và CSS interface để duyệt tài liệu bạn tải. XPath là ngôn ngữ truy vấn cho phép chọn node từ tài liệu XML. CSS selector quen thuộc hơn với người mới. Giống như viết style, CSS selector giúp dễ dàng nhắm mục tiêu các phần cụ thể của trang để trích xuất. Bạn chỉ cần cho Nokogiri biết bạn muốn gì khi nhắm đến đích cụ thể.

Pages

Chúng ta luôn cần bắt đầu bằng cách tải trang thực sự quan tâm. Chúng ta chỉ định loại tài liệu Nokogiri muốn parse – XML hoặc HTML:

some_scraper.rb

Nokogiri::XML và Nokogiri::HTML chấp nhận đối tượng IO hoặc String. Điều xảy ra ở trên rất trực quan. Mở và tải trang chỉ định dùng open-uri sau đó load cấu trúc XML/HTML vào tài liệu Nokogiri mới. XML không phải thứ người mới thường gặp. Do đó, tôi khuyên tập trung vào parse HTML cho lúc này. Tại sao open-uri? Module này từ Ruby Standard Library cho phép lấy trang web без phiền toái. Vì đối tượng IO được chấp nhận, chúng ta dễ dàng dùng open-uri.

API

Hãy thực hành với ví dụ nhỏ:

at_css

some_podcast_scraper.rb

Điều chúng ta làm ở đây đại diện cho tất cả các bước thường gặp trong web scraping – chỉ ở mức vi mô. Chúng ta quyết định URL cần thiết, tải trang, load vào tài liệu Nokogiri mới. Sau đó mở trang và nhắm mục tiêu phần cụ thể.

Ở đây tôi chỉ muốn biết tiêu đề tập mới nhất. Dùng phương thức at_css và CSS selector cho h2.post-title là đủ để nhắm điểm trích xuất. Với phương thức này, chúng ta chỉ scrape phần tử đơn lẻ. Nó cho cả selector – hầu như không phải thứ chúng ta cần. Do đó, trích xuất chỉ phần văn bản bên trong node qua phương thức text. Để so sánh, xem đầu ra cho cả header và text bên dưới.

Đầu ra

Mặc dù ví dụ này ứng dụng hạn chế, nhưng nó chứa tất cả nguyên liệu, tất cả bước bạn cần hiểu. Tôi thấy cool vì sự đơn giản. Vì có thể không rõ từ ví dụ này, tôi muốn chỉ ra công cụ này mạnh đến đâu. Hãy xem chúng ta còn làm gì nữa với script Nokogiri.

Chú ý!

Nếu bạn là người mới và không chắc cách nhắm HTML cần thiết, tôi khuyên tìm online cách kiểm tra nội dung trang web trong trình duyệt. Gần như tất cả trình duyệt lớn làm điều này rất dễ dàng hiện nay.

Trên Chrome, bạn chỉ cần right-click vào phần tử trên trang và chọn inspect. Sẽ mở cửa sổ nhỏ ở dưới trình duyệt hiển thị giống như "X-quang" DOM của trang. Nó có nhiều tùy chọn hơn, tôi khuyên dành thời gian Google để tự học. Thời gian dành cho việc này rất đáng giá!

css

Phương thức css sẽ cho chúng ta không chỉ một phần tử đơn lẻ mà bất kỳ phần tử nào khớp tiêu chí tìm kiếm trên trang. Rất gọn gàng và trực quan!

some_scraper.rb

Đầu ra

Khác biệt nhỏ trong ví dụ này là tôi lặp qua raw headers trước. Tôi cũng trích xuất inner text bằng phương thức text. Nokogiri tự động dừng ở cuối trang và không tự động theo dõi phân trang.

Giả sử chúng ta muốn thêm thông tin, ví dụ ngày và phụ đề cho mỗi tập. Chúng ta chỉ cần mở rộng ví dụ trên. Là ý tưởng tốt để làm từng bước. Làm một mảnh nhỏ chạy được rồi thêm độ phức tạp dần.

some_scraper.rb

Đầu ra

Lúc này, chúng ta đã có dữ liệu để "chơi". Chúng ta có thể cấu trúc hoặc "xé toạc" tùy ý. Trên chỉ để hiển thị dữ liệu dễ đọc. Tất nhiên chúng ta có thể đào sâu hơn vào từng mục bằng regex với phương thức text.

Chúng ta sẽ xem chi tiết hơn khi giải quyết bài toán podcast thực tế. Không phải lớp học regex, nhưng bạn sẽ thấy thêm nó hoạt động – đừng lo, không nhiều đến mức làm não bạn chảy máu.

Attributes

Thứ có thể hữu ích ở giai đoạn này là trích xuất href cho từng tập. Nó không thể đơn giản hơn.

some_scraper.rb

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

Để có URL hoàn chỉnh và hữu dụng, tôi lưu domain gốc vào biến và xây dựng URL đầy đủ cho mỗi tập.

Hãy nhìn nhanh đầu ra:

Đầu ra

Gọn gàng, phải không? Bạn có thể làm tương tự để trích xuất [:class] của selector.

Nếu node đó có nhiều class, bạn sẽ nhận được danh sách tất cả chúng.

Điều hướng Node

  • parent
  • children
  • previous_sibling
  • next_sibling

Chúng ta quen làm việc với cấu trúc cây trong CSS hoặc thậm chí jQuery. Sẽ đau khổ nếu Nokogiri không cung cấp API tiện lợi để di chuyển trong cây như vậy.

some_scraper.rb

Đầu ra

Như bạn tự thấy, đây là thứ khá mạnh – đặc biệt khi thấy .parent thu thập được nhiều thứ trong một lần. Thay vì định nghĩa nhiều node thủ công, bạn có thể thu thập hàng loạt.

Bạn thậm chí có thể chain chúng cho duyệt phức tạp hơn. Bạn có thể làm phức tạp tùy thích, nhưng tôi khuyên giữ mọi thứ đơn giản. Nó nhanh chóng trở nên cồng kềnh và khó hiểu. Nhớ: "Keep it simple, stupid!"

some_scraper.rb

Đầu ra

Lời kết

Nokogiri không phải thư viện khổng lồ, nhưng nó cung cấp nhiều thứ. Tôi khuyên bạn tự thực hành những gì đã học và mở rộng kiến thức qua tài liệu khi gặp khó khăn. Nhưng đừng tự rước rắc!

Phần giới thiệu nhỏ này sẽ đưa bạn lên đường hiểu được bạn có thể làm gì và nó hoạt động như thế nào. Tôi hy vọng bạn sẽ tự khám phá thêm và vui vẻ với nó. Như bạn sẽ tự khám phá, đây là công cụ phong phú và không ngừng cho.