Hướng dẫn lấy dữ liệu web, Web Crawling với Selenium - Python - WebDrive

Đăng bởi:

Trần Minh Trọng

Đăng ngày:

May 31, 2021

Đăng ở:

Kiến Thức Cơ Bản

Bài viết này chúng ta tìm hiểu cách sử dụng Selenium và Python để thu thập và tương tác với bất kỳ trang web nào.

Selenium là gì?

Selenium là công cụ tự động hóa trình duyệt web ban đầu được thiết kế để tự động hóa các ứng dụng web cho mục đích thử nghiệm (testing). Nó hiện được sử dụng cho nhiều ứng dụng khác như tự động hóa các tác vụ quản trị dựa trên web, tương tác với các nền tảng không cung cấp Api, cũng như để thu thập thông tin web (web crawling).

 

Tại sao chúng ta cần Selenium?

  • Hỗ trợ nhiều ngôn ngữ: Python, Java, C#, PHP, Ruby ...
  • Hỗ trợ javascrip: bạn có thể truy cập vào các thông tin ẩn của website bởi javascript, ajax bằng việc mô phỏng các hành vi giống với người dùng
  • Tính tích hợp cao: dễ dàng tích hợp với Maven, Jenkins, Docker

Điểm yếu của Selenium là tốc độ và khó chạy song song, nó cần sử dụng nhiều tài nguyên hệ thống. Do đó nếu tốc đọ không phải vấn đề bạn mới nên sử dụng Selenium, nó thích hợp với việc crawl các trang web phức tạp.

 

Cài đặt project Selenium Python

Trong bài này chúng ta sẽ sử dụng Python 3.x để thực hiện. Sau khi máy tính đã có Python chúc ta sẽ tiếp tục cài đặt các thành phần khác:

Cài đặt virtual environment

Virtual environment là môi trường ảo để cài đặt Selenium Python bên trong, dùng commandline cd vào thư mục mà bạn muốn dùng làm project và chạy các dòng lệnh sau:

virtualenv selenium_python
source selenium_python/bin/activate
pip install selenium

 

Cài đặt Chrome Drive

Truy cập và cài đặt phiên bản Chrome Drive , nếu trên máy tính đã cài sẵn trình duyệt Chrome bạn nên chọn phiên bản giống với phiên bản trình duyệt Chrome trên máy: https://sites.google.com/a/chromium.org/chromedriver/downloads

Khởi chạy phiên bản Chrome đầu tiên

Tạo file bot.py trong thư mục selenium_python và bắt đầu code

Import các packages:

from selenium import webdriver
from selenium.webdriver.chrome.options import Options

Thêm 1 số option cho chrome như kích thước windows, chế độ ẩn danh, ...

chrome_options = Options()
chrome_options.add_argument("--incognito")
chrome_options.add_argument("--window-size=1920x1080")

Khởi tạo đối tượng

driver = webdriver.Chrome(chrome_options=chrome_options, executable_path="đường_dẫn_đến_file_chrome_driver")

đường_dẫn_đến_file_chrome_driver bạn thay bằng đường dẫn đén file drive download ở bước trên, vd: "/Users/tuantai/Downloads/chromedriver"

Ok bây giờ có thể chạy thử bot này bằng lệnh: python bot.py ứng dụng chrome ở chế độ ẩn danh sẽ được mở lên.

 

Tạo request đầu tiên của bạn

Trong ví dụ này, chúng ta sẽ sử dụng Selenium để lấy tiêu đề tin tức trên Hacker News. Bạn có thể thử lại bằng: python bot.py

url = "https://news.ycombinator.com/"
driver.get(url)

 

Đợi response từ trang

Bản chất Javascript là không đồng bộ, vì vậy một số phần tử có thể không được tải đầy đủ và hiển thị ngay lập tức. Trong thực tế, nên thêm một số thời gian trễ trước khi nhận được phản hồi. Thay dòng code trên bằng

import time
url = "https://news.ycombinator.com/"
driver.get(url)
time.sleep(3)

Trong trường hợp này (time.sleep), chúng ta tạm dừng 3 giây trước khi phân tích dữ liệu. Nhiều kỹ thuật đợi respon phức tạp hơn sau này bạn có thể tìm với WebDriverWait

 

Tương tác với dữ liệu

Selenium cung cấp một số cách để truy cập các phần tử trên trang (https://selenium-python.readthedocs.io/locating-elements.html). Các phương pháp thường được sử dụng là:

  • Elements by id: cách này bạn sẽ cần kiểm tra mã nguồn và tìm id của phần tử
  • Elements by css_selector: css selector là một cách rất hiệu quả để chọn các phần tử trên một trang
  • Elements by Xpath: là một ngôn ngữ truy vấn để chọn các nút từ một tài liệu XML
##Find elements with Selenium
#by_id
els = driver.find_elements_by_id(elementId)
#by css
els = driver.find_elements_by_css_selector(element_css_selector)
#by xpath
els = driver.find_elements_by_xpath(element_x_path)

Quay về ví dụ đang làm trong bài này, ta lấy các phần tử theo css selector

elements = driver.find_elements_by_css_selector(".storylink")

Selenium trả về các đối tượng mà sau đó bạn có thể truy vấn. Ví dụ, nếu bạn muốn nhận:

  • text hiển thị trong phần tử: el.text
  • đường dẫn href url: el.get_attribute(“href”)
  • thuộc tính src : el.get_attribute(“src”)

Vì vậy, nếu chúng ta muốn lấy tiêu đề văn bản và url của các bài viết bằng Selenium:

elements = driver.find_elements_by_css_selector(".storylink")
storyTitles = [el.text for el in elements]
storyUrls = [el.get_attribute("href") for el in elements]

Tương tự nếu bạn muốn lấy score và domain của từng bài viết:

elements = driver.find_elements_by_css_selector(".score")
scores = [el.text for el in elements]
elements = driver.find_elements_by_css_selector(".sitebit a")
sites = [el.get_attribute("href") for el in elements]

Tổng kết nội dung của bot đầu tiên

from selenium import webdriver
from selenium.webdriver.chrome.options import Options
import time
chrome_options = Options()
chrome_options.add_argument("--incognito")
chrome_options.add_argument("--window-size=1920x1080")
driver = webdriver.Chrome(chrome_options=chrome_options, executable_path="đường_dẫn_đến_file_chrome_driver")
url = "https://news.ycombinator.com/"
driver.get(url)
time.sleep(3)
elements = driver.find_elements_by_css_selector(".storylink")
storyTitles = [el.text for el in elements]
storyUrls = [el.get_attribute("href") for el in elements]
elements = driver.find_elements_by_css_selector(".score")
scores = [el.text for el in elements]
elements = driver.find_elements_by_css_selector(".sitebit a")
sites = [el.get_attribute("href") for el in elements]

print(storyTitles)
print(storyUrls)
print(scores)
print(sites)
selenium-python-crawl-bot

 

 

Như vậy bạn đã biết cách lấy thông tin cụ thể trên một trang web bằng Selenium. Selenium cũng cung cấp các điều khiển nâng cao hơn như nhấp chuột, chèn dữ liệu vào input ... cực kỳ mạnh mẽ khi thu thập dữ liệu các trang web phức tạp hơn. Sau đây là 1 số ví dụ nâng cao để các điểm nổi bật Selenium có thể làm được:

Thực thi Javascript

Click button

el = driver.find_element_by_css_selector("css_selector")
#option 1: regular click
el.click()
#option 2: inject js
driver.execute_script("arguments[0].click();", el)

 

Cuộn chuột

driver.execute_script("window.scrollTo(0, document.body.scrollHeight);")

 

Truy cập vào các link trên trang

#find all the links
links = driver.find_elements_by_partial_link_text('')
#get the first one
l = links[0]
#click on it
driver.execute_script("arguments[0].click();", l)

 

Tối ưu lưu lượng tải

Vô hiệu hóa hiển thị hình ảnh

chrome_options = Options()
prefs={"profile.managed_default_content_settings.images": 2}
chrome_options.add_experimental_option('prefs', prefs)

 

Tạo cache

chrome_options = Options()
prefs={'disk-cache-size': 4096}
chrome_options.add_experimental_option('prefs', prefs)

 

Chạy ngầm (không hiển thị UI trình duyệt)

chrome_options = Options()
chrome_options.add_argument("--headless")

 

Chụp ảnh màn hình

driver = webdriver.Chrome()
driver.get('https://twitter.com/')
driver.save_screenshot("screenshot.png")
driver.close()

 

Tải ảnh

 

import urllib
from selenium import webdriver

driver = webdriver.Chrome()
driver.get('https://twitter.com/')

# get the image source
img = driver.find_element_by_css_selector('.Icon--bird')
src = img.get_attribute('src')

# download the image
urllib.urlretrieve(src, "twitter_icon.png")
driver.close()

 

Thực thi chuỗi hành động

 

menu = driver.find_element_by_css_selector(".nav")
hidden_submenu = driver.find_element_by_css_selector(".nav #submenu1")

ActionChains(driver).move_to_element(menu).click(hidden_submenu).perform()

 

Truy cập với proxies

 

from selenium import webdriver

PROXY = "99.99.99.99:1111" # IP:PORT or HOST:PORT

chrome_options = webdriver.ChromeOptions()
chrome_options.add_argument('--proxy-server=%s' % PROXY)
driver = webdriver.Chrome(chrome_options=chrome_options)
driver.get("http://whatismyipaddress.com")

 

Cuộn chuột trong 1 thẻ Select

from selenium.webdriver.support.ui import Select
value = "optionValue"
element = Select(driver.find_element_by_tag_name("select")
for option in element.options: 
if option.get_attribute("value") == value: 
element.select_by_visible_text(option.text)

 

Còn rất nhiều điều Selenium có thể làm được bạn có thể tham khảo ở các link tài liệu sau:
https://www.selenium.dev/documentation/en/webdriver/
https://selenium-python.readthedocs.io/

Nguồn: https://trinhtuantai.com/huong-dan-lay-du-lieu-web-web-crawling-voi-selenium-python-webdrive.html

default_image
Tác giả: Trần Minh Trọng
ADMIN

Bình luận

Để lại bình luận

Email và số điện thoại sẽ không được công khai. Những trường bắt buộc được đánh dấu *

Repository deleted Your repository has remove
Loading