# Selenium 慢慢爬(2):簡易指令與操作網頁
第一部:https://hackmd.io/@gdw7l5sPTOyNv76kZ_twjA/H1X9Suinq
安裝完成之後來體驗一下 selenium 的基礎搜尋函數最後再來進行動態操作網頁以及簡單的爬取文章
## 基礎函數
### find_element
>* find_element:抓取符合條件的第一個項目。
>* find_elements:抓取所有符合條件的項目回傳成list。
可以直接使用函數指定選擇器
或是使用BY 指定選擇器
```=
from selenium import webdriver
from selenium.webdriver.common.by import By
# 抓取第一個
driver.find_element_by_id ("example")
driver.find_element(By.ID, "example")
# 抓取所有
driver.find_elements_by_id ("example")
driver.find_elements(By.ID, "example")
```
### 選擇器
根據原始碼上的元素來指定選擇器
1. ID = id
1. CLASS_NAME = class_name
1. NAME = name
1. LINK_TEXT = link_text
href(帶有連結的屬性)對應的文字內容才行

3. PARTIAL_LINK_TEXT = partial_link_text
類似於LINK_TEXT方法,但只需要部份文字即可
5. TAG_NAME = tag_name
使用HTML標籤名稱(即TAG),來抓取網頁元素

但是使用TAG選擇器特別要注意的是,HTML標籤時常重複,因此TAG選擇器通常適用於抓取大框架的網頁元素再做細部搜尋。
7. XPATH = xpath
容易失敗,不建議使用
## 自動搜尋網頁關鍵字並爬取標題
以dcard為例
### 1.創建py檔並獲取webdriver的位置
```bash=
from selenium import webdriver
PATH="windows中 webdriver的位置"#若與py檔放在同一個資料夾中就可以不用
driver = webdriver.Chrome()
```
### 2.獲取網頁網址
get可以讓瀏覽器連接上該網址的網頁
```bash=
#連接上dcard
driver.get("https://www.dcard.tw/f")
```
### 3.在搜尋欄打上關鍵字
檢視網頁的原始碼
於搜尋欄的位置按下右鍵並點擊檢查就會跳出原始碼

會顯示許多tag 這裡使用class name 作為尋找的元素

>* find_element(tag,名稱):尋找元素
>* send_keys(): 打上關鍵字
```bash=
element = driver.find_element('name','query')
element.send_keys('板橋美食')
```
### 4.操作鍵盤指令送出關鍵字
需要使用鍵盤指令要 import keys
常用的指令:
send_keys(Keys.BACK_SPACE) #刪除鍵(BackSpace)
send_keys(Keys.SPACE) #空格鍵(Space)
send_keys(Keys.TAB) #製表鍵(Tab)
send_keys(Keys.ESCAPE) #回退鍵(Esc)
send_keys(Keys.ENTER) #回車鍵 Enter)
send_keys(Keys.CONTROL,'a') #全選(Ctrl+A)
send_keys(Keys.CONTROL,'c') #複製(Ctrl+C)
send_keys(Keys.CONTROL,'x') #剪切(Ctrl+X)
send_keys(Keys.CONTROL,'v') #粘貼(Ctrl+V)
send_keys(Keys.F1) #鍵盤 F1
send_keys(Keys.F12) #鍵盤 F12
```bash=
from selenium.webdriver.common.keys import Keys
element.send_keys(Keys.RETURN)#按下enter鍵的意思
```
### 5.爬取文章標題
先觀察標題的原始碼是否有相同之處
這裡的標籤class name 都是相同的,可作為共同元素
>* 尋找多相同標籤的元素:.find_elements_by_class_name('class name')
>* 顯示內文:.text

```bash=
titles=driver.find_elements_by_class_name('sc-8fe4d6a1-3')
for title in titles:
print(title.text)
#停留10秒
time.sleep(10)
#關掉視窗
driver.quit()
```
### 6.修正跳轉問題(1)
網頁從首頁跳到搜尋頁面需要跳轉時間
會造成爬搜尋頁面的標題時出錯
可以再跳轉後 爬蟲前稍作停留等待跳轉結束再開始爬蟲
```bash=
element.send_keys(Keys.RETURN)#頁面跳轉需要時間
time.sleep(3)#停留3秒再繼續
for title in titles:
print(title.text)
time.sleep(10)
driver.quit()
```
### 7.修正跳轉問題(2)
設定停留時間是可行的方法,但是每次的跳轉時間不同,此種方法比較浪費時間
使用wait until 讓跳轉後的特定資訊出現時就接續後面的流程,減少不必要的等待時間
```bash=
#wait until所需的module
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
element.send_keys(Keys.RETURN)#頁面跳轉需要時間
##等待瀏覽器一定的時間直到某元素出現
WebDriverWait(driver, 10).until(
EC.presence_of_element_located((By.CLASS_NAME, "sc-f860e6e9-1"))
)
titles=driver.find_elements_by_class_name('sc-8fe4d6a1-3')
```
### 完整code
```bash=
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
import time
PATH="C:/Users/tkbuser/Desktop/workplace/selenium/chromedriver.exe"
driver = webdriver.Chrome()
driver.get("https://www.dcard.tw/f")
element = driver.find_element('name','query')
element.send_keys('板橋美食')
element.send_keys(Keys.RETURN)#頁面跳轉需要時間
##等待瀏覽器一定的時間直到某元素出現
WebDriverWait(driver, 10).until(
EC.presence_of_element_located((By.CLASS_NAME, "sc-f860e6e9-1"))
)
titles=driver.find_elements_by_class_name('sc-8fe4d6a1-3')
# titles=driver.find_elements_by_class_name('sc-8fe4d6a1-3')
for title in titles:
print(title.text)
time.sleep(10)
driver.quit()
```