Python 的 selenium 的一些使用

本文记录 Python 使用 Selenium 的一些操作,主要是为了方便以后查阅使用。对于一些网站的爬虫由于 js 脚本的加载使得爬虫的难度增大,因此可以考虑使用 Selenium 库来帮助我们,用它操纵浏览器来爬取需要的数据。


以下为本文涉及的需要加载的包。

1
2
3
4
5
6
7
8
9
10
11
import time
import re
import random
import pyautogui
from fake_useragent import UserAgent
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.chrome.options import Options
# from lxml import etree, html


首先是使用一个随机的 userAgent,其次是设定初始打开的链接地址。注意设置你的 webdrive 的地址。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
import time
from fake_useragent import UserAgent
from selenium import webdriver

user_agent = UserAgent().random

chromeOptions = webdriver.ChromeOptions()
chromeOptions.add_argument(f'user-agent={user_agent}')
star_url = r"https://wenku.baidu.com/view/8844f45e15791711cc7931b765ce0508763275cf.html"


webdrive = r'D:/your/chromedriver.exe'
driver = webdriver.Chrome(webdrive, chrome_options=chromeOptions)

driver.get(star_url)
time.sleep(1)
# close the browser
# driver.close()

这里用的浏览器是 chrome ,可以看到成功打开了百度文库,但是目前什么操作都没做。

接下来可以做点简单的操作。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
# 获取网页的源码,可用于 lxml 的库的分析。但是 selenium 库其实也有选择器,挑选自己喜欢的方式即可
with open('baidu.html','w', encoding="utf-8") as f:
f.write(driver.page_source)
f.close()


# 滑到页面底部,参考 https://stackoverflow.com/questions/20986631/how-can-i-scroll-a-web-page-using-selenium-webdriver-in-python
SCROLL_PAUSE_TIME = 0.5

last_height = driver.execute_script("return document.body.scrollHeight")

while True:
driver.execute_script("window.scrollTo(0, document.body.scrollHeight);")
time.sleep(SCROLL_PAUSE_TIME)
new_height = driver.execute_script("return document.body.scrollHeight")
if new_height == last_height:
break
last_height = new_height

# 滑动页面 水平 0,竖直 -2000 个像素点

driver.execute_script("window.scrollBy(0,-1500)")

# 通过 xpath 的方法找到对应的 element 并且点击,例如 继续阅读 的按钮 必须在浏览器能看到的范围内才可以点击
driver.find_element_by_xpath('//*[@id="html-reader-go-more"]/div[2]/div[1]/span/span[2]').click()

# 将窗口放大到特定的大小
driver.set_window_size(520, 1080)

# 将窗口放大到最大
driver.maximize_window()


# 保存网页截图,只会保存能看到的部分
driver.save_screenshot('screenshot.png')

# 保存某个元素范围的截图,例如百度文库的 Logo
image = driver.find_element_by_xpath('//*[@id="hd"]/div/div[1]/div[1]/a/span').screenshot_as_png
with open('baidu.png','wb') as f:
f.write(image)
f.close()


# 获取总页码
import re
s_page_number = driver.find_element_by_class_name('page-count').text
print(s_page_number)
# '/26' 不是我们想要的直接结果,通过正则将 26 提取出来
page_number = re.findall('/([0-9]+)', s_page_number)[0]
print('一共有'+page_number +'页')

下面是在页面里面可输入交互的地方输入内容,并且点击.一下都是使用 xpath 进行元素定位.

1
2
3
4
5
6
7
8
9
10
# 输入内容并且跳转 注意适当加入一些休息时间
element = driver.find_element_by_xpath('//*[@id="kw"]')
element.clear() # 清除原本在的数据
time.sleep(1)
element.send_keys('量子力学') # 输入新的
time.sleep(1.5)
driver.find_element_by_xpath('//*[@id="sb"]').click()
time.sleep(1)

# driver.close()

如何新开一个 tag 并且关闭?可以参考如下的操作

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
import time
from selenium import webdriver

chromeOptions = webdriver.ChromeOptions()
star_url = r"https://camusecao.top/"

webdrive = r'D:/your/chromedriver.exe'
driver = webdriver.Chrome(webdrive, chrome_options=chromeOptions)
driver.get(star_url)

# 参考 https://stackoverflow.com/questions/28431765/open-web-in-new-tab-selenium-python 和 https://stackoverflow.com/questions/38154483/using-selenium-webdriver-in-python-to-open-link-in-new-tab-window https://stackoverflow.com/questions/25951968/open-and-close-new-tab-with-selenium-webdriver-in-os-x

time.sleep(5)
element = driver.find_element_by_xpath('//*[@id="sidebar"]/div/div[1]/div/div[4]/ul/li/a')
driver.execute_script('arguments[0].click();', element)
time.sleep(4)
# 聚焦到新开的 tab
driver.switch_to_window(driver.window_handles[1])
# 关闭这个 tab
driver.close()


# driver.execute_script("window.open('');")
# driver.switch_to.window(driver.window_handles[1])
# driver.get(url)

有些网页并不是一下子就加载全部的内容,可能要等到你滑动那里才加载。那么如果确保我们等待的时间不会过长呢?可以用 wait 的方法,检测到元素后再行动。比如等到某个元素加载好点击下一页.

1
2
3
4
5
6
7
8
9
10
11
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.chrome.options import Options
# 设定等待时间为 5s
wait = WebDriverWait(driver, 5)
the_path = '//div[contains(@data-id,"5")]/img'
try:
wait.until(EC.element_to_be_clickable((By.XPATH, the_path)))
driver.find_element_by_xpath('//*[@id="newView"]/div[1]/div/a[4]/i').click()
time.sleep(random.random() + 0.05)

下面是直接调用 chrome 来实现保存网页的方法。

1
2
3
4
5
6
7
8
9
10
import os 
import pyautogui

pyautogui.hotkey('ctrl', 's')
time.sleep(1)
save_file = os.getcwd()+'\save'
pyautogui.typewrite(save_file)
time.sleep(1)
pyautogui.hotkey('enter')
time.sleep(4)

Welcome to my other publishing channels