12/08/2018, 13:45

Web crawler với Selenium Webdriver và PhantomJS - Phần 2

I, Mở đầu Ở bài viết trước, chúng ta đã tìm hiểu về Selenium webdriver. Công cụ giúp crawl những trang web khó, những trang mà generate HTML bởi các hàm Javascript. Việc sử dụng Selenium webdriver trên những trình duyệt truyền thống như firefox, chrome, IE... đã bộc lộ những hạn chế như: tiêu ...

I, Mở đầu

Ở bài viết trước, chúng ta đã tìm hiểu về Selenium webdriver. Công cụ giúp crawl những trang web khó, những trang mà generate HTML bởi các hàm Javascript.

Việc sử dụng Selenium webdriver trên những trình duyệt truyền thống như firefox, chrome, IE... đã bộc lộ những hạn chế như: tiêu tốn bộ nhớ, tốc độ chậm...Phantomjs ra đời để giải quyết một phần chuyện đó , nó có hẳn một thư viện mở rộng giúp bạn sử dụng dễ dàng hơn đó là casperjs.

II, Giới thiệu

Phantomjs là một “headless browser”, dựa trên webkit và v8 nên sẽ chạy như một trình duyệt , các chức năng mọi thứ được thông qua dòng lệnh , không giống như chrome hay firefox thông qua giao diện.

Để cài đặt phantomJS, phiên bản mới nhất hiện tại là 2.1.1:

    npm install phantomjs -g

Việc khởi tạo driver trên phantomJS cũng giống như các trình duyệt thông thường khác:

    driver = Selenium::WebDriver.for :phantomjs

Chúng ta sẽ tìm hiểu một số option hay dùng khi khai báo driver cho phantomJS:

  • --ignore-ssl-errors=[true|false]: driver sẽ bỏ qua lỗi SSL khi access vào site, như lỗi expired hoặc certificate. Giá trị default là false, cũng có thể set giá trị là yes|no.

  • --ssl-protocol=[sslv3|sslv2|tlsv1|any']: set giao thức ssl cho kết nối an toàn, mặc định là sslv3

  • --web-security=[true|false]: cho phép web security và ngăn chặn cross-domain XHR, default là true, cũng có thể set giá trị là yes|no.

  • --cookies-file=/path/to/cookies.txt: chỉ định cụ thể tệp tin lưu trữ cookies.

  • --proxy=address:port: quy định proxy server để sử dụng, ví dụ: proxy=192.168.1.42:8080

  • --script-encoding=encoding: thiết lập encode khi bắt đầu các script, mặc định là utf8.

Để tìm hiểu chi tiết hơn, các bạn có thể vào: http://phantomjs.org/release-2.1.html

III, Ví dụ

Tiếp theo chúng ta sẽ làm một ví dụ nhỏ:

"In ra tên công ty, lương của các tin tuyển dụng về IT- Phần mềm có mức lương min trên 700$$tại Hà Nội trong một tháng gần đây trên trang Vietnamworks"

  • Trước tiên cần install phantomjs về máy nếu chưa có:
    npm install phantomjs -g
  • Add gem đến Gemfile:
    gem 'selenium-webdriver'
  • Tạo một file ruby, trên đó khởi tạo selenium kèm các options cần thiết:
    require "selenium-webdriver"

    options = {
      "phantomjs.cli.args" => [
        "--ssl-protocol=any",
        "--ignore-ssl-errors=true",
        "--web-security=false",
        "acceptSslCerts=true"
      ]
    }

    capabilities = Selenium::WebDriver::Remote::Capabilities.phantomjs(options)
    Selenium::WebDriver.for(:phantomjs, desired_capabilities: capabilities)
  • Access đến trang chủ của viblo:
    http://www.vietnamworks.com/"
  • Click select box tìm việc:
    driver.find_element(id: "select2-chosen-1").click
  • Chọn job IT-Phần mềm:
    driver.find_elements(xpath: "//li/div/span/..").find{|e| e.text == "IT - Phần mềm"}
  • Chọn khu vực Hà Nội:
    driver.find_element(id: "select2-chosen-2").click
    driver.find_elements(xpath: "//li/div/span/..").find{|e| e.text == "Hà Nội"}
  • Submit form:
    driver.find_element(class: "btn-search-all").click
  • Danh sách các tin đạt yêu cầu:
    results = []
    begin
        driver.find_elements(class: "job-item").each do |item|
            break if item.find_element(css: "div.extra-info.salary").text.split("-")[0] < "$700"
            break unless item.find_element(css: "div.extra-info.location.text-clip).text.include?("Hà Nội")
            results << {
                name: item.find_element(css: "div.company").text,
                salary: item.find_element(css: "div.extra-info.salary").text
            }
        end
        driver.find_elements(css: "a.ais-pagination--link")[-2].click
    end while driver.find_elements(css: "a.ais-pagination--link").last.text != "»"
  • In ra danh sách tìm được:
    results.each do |result|
        puts "Company_name: #{result[:name]}, Salary: #{result[:salary]}"
    end

IV, Kết luận

Trên đây là giới thiệu và ví dụ về việc ứng dụng Selenium webdriver với phantomjs dùng trong Web crawler. Chi tiết hơn, có thể tham khảo tại: http://www.rubydoc.info/gems/selenium-webdriver/2.47.1/Selenium/WebDriver/PhantomJS/Bridge

0