爬虫Part5——Selenuim

[TOC]

Selenuim简介

  • 有些网页的响应内容经过复杂的加密,通过手动调试解密已经非常地狱,所以可以尝试直接获取浏览器运行后的结果。

  • selenium本体是自动化测试工具,控制浏览器操作。

1
2
3
4
5
6
7
8
9
from selenium import webdriver

url = "https://www.baidu.com"

# 下载的文件名是msedgedriver.exe,默认启动为MicrosoftWebDriver.exe,修正一下文件名就可以不用给.Edge()传文件名参数了
driver = webdriver.Edge() # 必须用已经在python路径中的driver启动
driver.get(url) # 打开某个网址

print(driver.title) # 百度一下,你就知道
  • 使用selenium需要:1. pip install selenium 2. 下载对应版本的浏览器driver并放在python根目录下
  • .get()打开某个网址

拉钩

元素获取与事件处理

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
from selenium.webdriver import Edge
from selenium.webdriver.common.keys import Keys

url = "http://lagou.com"

driver = Edge()
driver.get(url)

# 用选择工具找到 '//*[@id="changeCityBox"]/p[1]/a' 或者下面都是可以的
ele = driver.find_element_by_xpath('//*[@id="changeCityBox"]/p[1]/a/i')
ele.click()

driver.find_element_by_xpath('//*[@id="search_input"]').send_keys("python", Keys.ENTER)

li_list = driver.find_elements_by_xpath('//*[@id="s_position_list"]/ul/li')
for li in li_list:
job_name = li.find_element_by_tag_name("h3").text
job_price = li.find_element_by_xpath("./div/div/div[2]/div/span").text
company_name = li.find_element_by_xpath('./div/div[2]/div/a').text
print(company_name, job_name, job_price)
  • find_element_by_xpath() 获取元素对象
  • .click() 使元素对象产生点击事件
  • .send_keys() 使元素对象填入文本
  • .text 获取元素内的文本

切换窗口与跳转frame

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
from selenium.webdriver import Edge
from selenium.webdriver.common.keys import Keys

web = Edge()

web.get("http://lagou.com")
web.find_element_by_xpath('//*[@id="changeCityBox"]/p[1]/a/i').click()
web.find_element_by_xpath('//*[@id="search_input"]').send_keys("python", Keys.ENTER)
web.find_element_by_xpath('//*[@id="s_position_list"]/ul/li[1]/div[1]/div[1]/div[1]/a/h3').click()

# 1. 在selenium的眼中,新窗口默认是不切换过来的,需要手动切换
web.switch_to.window(web.window_handles[-1])

# 在新窗口中提取内容
job_detail = web.find_element_by_xpath('//*[@id="job_detail"]/dd[2]/div').text
print(job_detail)

# 关掉子窗口,或者返回上一页面
web.close()
# web.back()

# 变更selenium的窗口视角,回到原来的窗口中
web.switch_to.window(web.window_handles[0])
print(web.find_element_by_xpath('//*[@id="s_position_list"]/ul/li[1]/div[1]/div[1]/div[1]/a/h3').text)

# 2. 跳转进入iframe
web.get("https://www.91kanju.com/vod-play/541-2-1.html")

# 先拿到iframe
iframe = web.find_element_by_xpath('//*[@id="player_iframe"]')
# 切换到iframe
web.switch_to.frame(iframe)
# 拿到数据
tx = web.find_element_by_xpath('//*[@id="main"]/h3[1]').text
print(tx)
web.switch_to.default_content() # 切换回原页面

  • switch_to.window(web.window_handles[-1]) 切换到最后一个标签
  • .close() 关闭标签
  • .back() 返回当前标签的上一页面
  • switch_to.frame(iframe) 切换到内嵌的html中

艺恩

无头浏览器

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
from selenium.webdriver import Edge
import time

# 准备好参数配置
from selenium.webdriver.support.select import Select

opt = {
# 这里是默认的
"browserName": "MicrosoftEdge",
"version": "",
"platform": "WINDOWS",
# 设置无头
"ms:edgeOptions": {
'extensions': [],
'args': [
'--headless',
'--disable-gpu',
'--remote-debugging-port=9222',
]}
}
web = Edge(capabilities=opt) # 把参数配置设置到浏览器中

web.get("https://www.endata.com.cn/BoxOffice/BO/Year/index.html")

# 拿到经过数据加载以及js执行之后的结果的html内容!!!这样可以结合选择工具直接定位了
print(web.page_source)

# 定位到下拉列表
sel_el = web.find_element_by_xpath('//*[@id="OptionDate"]')
# 对元素进行包装, 包装成下拉菜单
sel = Select(sel_el)
# 让浏览器进行调整选项
for i in range(len(sel.options)): # i就是每一个下拉框选项的索引位置
sel.select_by_index(i) # 按照索引进行切换
time.sleep(2)
table = web.find_element_by_xpath('//*[@id="TableList"]/table')
print(table.text) # 打印所有文本信息
print("===================================")

web.close() # 关闭页面
web.quit() # 关闭浏览器

  • .quit() 关闭浏览器
  • web.page_source 拿到经过数据加载以及js执行之后的结果的html内容!!!这样可以结合选择工具直接定位了
  • Select(sel_el).select_by_index(i) 将元素包装成下拉菜单并按照索引进行切换
1
2
3
4
5
6
# chrome设置无头
chrome_options = webdriver.ChromeOptions()
chrome_options.add_argument('--headless')
chrome_options.add_argument('--disable-gpu')

driver = webdriver.Chrome(options=chrome_options)

超级鹰

验证码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
from selenium.webdriver import Edge
from chaojiying import Chaojiying_Client
import time

web = Edge()
web.get("http://www.chaojiying.com/user/login/")

# 处理验证码
img = web.find_element_by_xpath('/html/body/div[3]/div/div[3]/div[1]/form/div/img').screenshot_as_png # 将元素组件以图像形式存储在内存
chaojiying = Chaojiying_Client('18614075987', '6035945', '914467')
dic = chaojiying.PostPic(img, 1902)
verify_code = dic['pic_str']

# 向页面中填入用户名, 密码, 验证码
web.find_element_by_xpath('/html/body/div[3]/div/div[3]/div[1]/form/p[1]/input').send_keys("18614075987")
web.find_element_by_xpath('/html/body/div[3]/div/div[3]/div[1]/form/p[2]/input').send_keys("6035945")
web.find_element_by_xpath('/html/body/div[3]/div/div[3]/div[1]/form/p[3]/input').send_keys(verify_code)

time.sleep(5)
# 点击登录
web.find_element_by_xpath('/html/body/div[3]/div/div[3]/div[1]/form/p[4]/input').click()
  • .screenshot_as_png 将元素组件以图像形式存储在内存

12306

反检测与滑块拖动

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
from selenium.webdriver import Chrome
from selenium.webdriver import ActionChains
from selenium.webdriver.chrome.options import Options
from chaojiying import Chaojiying_Client
import time

chaojiying = Chaojiying_Client('18614075987', '6035945', '914467')

option = Options()
option.add_argument('--disable-blink-features=AutomationControlled')

web = Chrome(options=option)
web.get("https://kyfw.12306.cn/otn/resources/login.html")
time.sleep(2)
web.find_element_by_xpath('/html/body/div[2]/div[2]/ul/li[2]/a').click()
time.sleep(3)

# 先处理验证码
verify_img_element = web.find_element_by_xpath('//*[@id="J-loginImg"]')

# 用超级鹰去识别验证码
dic = chaojiying.PostPic(verify_img_element.screenshot_as_png, 9004)
result = dic['pic_str'] # x1,y1|x2,y2|x3,y3
rs_list = result.split("|")
for rs in rs_list: # x1,y1
p_temp = rs.split(",")
x = int(p_temp[0])
y = int(p_temp[1])
# 鼠移动标 -> 点击 -> 执行.perform()
ActionChains(web).move_to_element_with_offset(verify_img_element, x, y).click().perform()
# time.sleep(5)

# 输入用户名和密码
web.find_element_by_xpath('//*[@id="J-userName"]').send_keys("userName")
web.find_element_by_xpath('//*[@id="J-password"]').send_keys("password")

# 点击登录
web.find_element_by_xpath('//*[@id="J-login"]').click()
time.sleep(5)

# 拖拽
btn = web.find_element_by_xpath('//*[@id="nc_1_n1z"]')
ActionChains(web).drag_and_drop_by_offset(btn, 300, 0).perform()
  • 拖动时不能切换页面
  • 适当使用 time.sleep(3) 防止过快
  • 事件链 ActionChains 必须在末尾协商执行语句 .perform()