iT邦幫忙

第 12 屆 iThome 鐵人賽

DAY 20
1
自我挑戰組

LINE BOT 新手村30日攻略系列 第 20

Day20 Python 爬蟲 Selenium

  • 分享至 

  • xImage
  •  

今天要來介紹的是另一種爬蟲, Selenium
這種爬蟲很特別的地方是,他是透過模擬使用者操作網頁的方式進行爬蟲

安裝

pip3

pip3 install selenium

實作

今天嘗試跟著網路上的教學做做看,雖然還沒找到不能使用 XPath 的原因,不過基本的操作還是可以的

參考 輕鬆學習 Python:透過操控瀏覽器擷取網站資料

定位元素

根據 Selenium Python 官方文檔 ,我們有幾種找到元素的方式

  • find_element_by_id
  • find_element_by_name
  • find_element_by_xpath
  • find_element_by_link_text
  • find_element_by_partial_link_text
  • find_element_by_tag_name
  • find_element_by_class_name
  • find_element_by_css_selector

我們可以先從簡單的 google 搜尋來嘗試看看

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

# 基本設定
options = Options()

# Chrome 位置
options.binary_location = "C:\\Program Files (x86)\\Google\\Chrome\\Application\\chrome.exe"

# webdriver 位置
webdriver_path = 'C:\\chromedriver.exe'
driver = webdriver.Chrome(executable_path=webdriver_path, options=options)

# 前往 google
driver.get('https://google.com')

# 輸入搜尋文字
search_elem = driver.find_element_by_name('q')
search_elem.send_keys('iThelp')

# 點擊搜尋按鈕
search_btn = driver.find_element_by_name('btnK')
search_btn.click()

# 關閉瀏覽器
#driver.close()

執行後就會發現以神速進行了搜尋w

接下來來嘗試看看文章的範例吧!

from pyquery import PyQuery as pq
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
from random import randint
import selenium.webdriver.support.ui as ui
import time

def get_movie_info(movie_url):
    """
    Get movie info from certain IMDB url
    """
    d = pq(movie_url)
    movie_rating = float(d("strong span").text())
    movie_genre = [x.text() for x in d(".subtext a").items()]
    movie_release_date = movie_genre.pop()
    movie_poster = d(".poster img").attr('src')
    movie_cast = [x.text() for x in d(".primary_photo+ td a").items()]

    # 回傳資訊
    movie_info = {
        "movieRating": movie_rating,
        "movieReleaseDate": movie_release_date,
        "movieGenre": movie_genre,
        "moviePosterLink": movie_poster,
        "movieCast": movie_cast
    }
    return movie_info

def get_movies(*args):
    """
    Get multiple movies' info from movie titles
    """
    imdb_home = "https://www.imdb.com/"
    options = Options()
    options.binary_location = "C:\\Program Files (x86)\\Google\\Chrome\\Application\\chrome.exe"
    webdriver_path = 'C:\\chromedriver.exe'
    driver = webdriver.Chrome(executable_path=webdriver_path, options=options)
    movies = dict()
    wait = ui.WebDriverWait(driver,10)
    for movie_title in args:
        # 前往 IMDB 首頁
        driver.get(imdb_home)
        # 定位搜尋欄位
        search_elem = wait.until(lambda driver:driver.find_element_by_name("q"))
        # 輸入電影名稱
        search_elem.send_keys(movie_title)
        # 定位搜尋按鈕
        submit_elem = wait.until(lambda driver:driver.find_element_by_id("suggestion-search-button"))
        # 按下搜尋按鈕
        submit_elem.click()
        # 限縮搜尋結果為「電影」類
        category_movie_elem = wait.until(lambda driver:driver.find_element_by_link_text("Movie"))
        # 按下限縮搜尋結果
        category_movie_elem.click()
        # 定位搜尋結果連結
        first_result_elem = wait.until(lambda driver:driver.find_element_by_xpath("//td[@class='result_text']/a"))
        # 按下搜尋結果連結
        first_result_elem.click()
        # 呼叫 get_movie_info()
        current_url = driver.current_url
        movie_info = get_movie_info(current_url)
        movies[movie_title] = movie_info
        time.sleep(randint(3, 8))
    driver.close()
    return movies

print(get_movies("Avengers: Endgame", "Captain Marvel"))
#driver.close()

回傳結果

在實作的過程中發現到,有時候明明可以確認該元素是存在,但是卻搜尋不到
在網路上尋找後發現是因為網頁還沒有完全加載完成,造成無法正確搜尋到
後來找到一個有效的解決方式是使用 selenium.webdriver.support.ui
他會在10秒內每500毫秒就檢查一次該元素是否存在

後記

這陣子大概是課業、升學兩頭燒
但是在鐵人賽也希望能好好完賽,最終造成的就是文章品質下降
我會在日後將幾篇內容欠缺的文章好好補齊,這樣也比較對得起自己w
這兩篇大概主要是提供資料讓各位嘗試時做看看,希望大家玩得開心

參考資料

輕鬆學習 Python:透過操控瀏覽器擷取網站資料
Selenium Python 官方文檔
python網路爬蟲教學-Selenium基本操作
CSDN 解決網頁元素無法定位的幾種方法


上一篇
Day19 Python 爬蟲 Beautiful Soup
下一篇
Day21 電影資訊查詢 - 1
系列文
LINE BOT 新手村30日攻略30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言