关于爬虫,欢迎先阅读一下我的前几篇文章😶‍🌫️😶‍🌫️😶‍🌫️:

「Python」爬虫-1.入门知识简介 - 掘金 (juejin.cn)

「Python」爬虫-2.xpath解析和cookie,session - 掘金 (juejin.cn)

「Python」爬虫-3.防盗链处理 - 掘金 (juejin.cn)

参考链接:

1. selenium教程-知乎

2. 什么是iframe及作用是什么? - 石海莹 - 博客园 (cnblogs.com)

selenium的使用

Selenium实际就是电脑模拟人操作浏览器网页,可以实现自动化、测试等基础操作。

使用前需要使用pip安装一下包:

pip install selenium -i https://pypi.tuna.tsinghua.edu.cn/simple

安装包之后需要安装一下浏览器的 驱动 ,(驱动-也就是用什么浏览器来进行自动化等一系列操作)

下载浏览器驱动

Chrome浏览器驱动: chromedriver , npm备用地址

Edge浏览器驱动: MicrosoftWebDriver

Firefox浏览器驱动: geckodriver

Opera浏览器驱动: operadriver

注意:如果下载的是chrome驱动,记得驱动要和自己浏览器版本对应起来,不然很有可能使用驱动失败~

下载完成之后需要把 浏览器驱动 放入 python安装所在的路径 (eg: D:/python/SoftWare/ )中,或者直接告知selenuim的驱动路径。

如果把浏览器驱动放入Python所在路径时,在实例化浏览器时的代码如下:

from selenium.webdriver import Chrome
# 创建浏览器
web = Chrome()

如果嫌麻烦,想直接实例化也是可以的,将selenium所在路径传递给Chrome即可。

import selenium.webdriver
# 告知selenium 驱动的具体位置
driver=webdriver.Chrome("/Users/xxx/Desktop/job/chromedriver")

来吧!实战!

这里以打开百度为例,具体代码如下:

# 让selenium打开百度
from selenium.webdriver import Chrome
# 创建浏览器
web = Chrome()
# 打开一个网址
web.get("http://www.baidu.com")
print(web.title)

上述代码帮助我们打开了百度,并且在控制台输出了title="百度一下,你就知道"。

从图中可以看到,浏览器标识了Chrome正在受到自动测试软件的控制,我们通过web.title就可以轻松的拿到页面中的<title>标签中的文字了。

在使用web.find元素时,看到很多博客仍然在使用,web.find_elements_by_xpath,但是最新版的selenium这个方法已经被弃用了 需要改为:

from selenium.webdriver.common.by import By
button=broser.find_element(By.XPATH,'//span')

知道寻找元素的方法之后,我们来个实战~

模拟向编辑框输入数据

比如遇到一些登录页面,需要我们填写用户名和密码,这时候selenium就有点作用了。通过 web.find_element(By.XPATH,"xxx")就可以获取到页面对应的元素,如果想向输入框填充数据,直接找到该元素,使用.send_keys()方法就可以填充内容,前提是你找得到的这个元素是<input>标签,即可以发送内容的标签,不然会报错的~

.send_keys()方法还支持出传递监听键盘事件,添加参数Keys.ENTER,就是填充内容之后模拟按下enter键,如果是在搜索框里,效果就会显示查找你输入的文字了。

下面以拉勾网为例,提取某个职位所在的公司,职位名称以及薪资情况。

具体使用方法如下:

让selenium输入并点击搜索按钮 from selenium.webdriver import Chrome from selenium.webdriver.common.keys import Keys from selenium.webdriver.common.by import By import time # 创建浏览器 web = Chrome() # 打开一个网址 web.get("http://lagou.com") # 找到某个元素,点击它 el = web.find_element(By.XPATH,'//*[@id="changeCityBox"]/p[1]/a') el.click() # 点击事件 time.sleep(1) # 让浏览器缓一会儿 # 找到输入框,输入python => 输入回车/点击搜索按钮 web.find_element(By.XPATH,'//*[@id="search_input"]').send_keys("python", Keys.ENTER) # 查找存放数据的位置,进行数据提取 # 找到页面中存放数据的所有li li_list = web.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)

整体思路: 通过F12键找到对应框的元素,并复制xpath,在实例化Chrome()对象之后,通过web.find_element(By.XPATH,"xxx")就可以获取到页面对应的元素。如果是是输入框,通过.send_keys("xx")就可以填充数据。send_keys方法还可以监听键盘按键,比如监听用户是否按下enter键。

窗口切换的场景,就是在用户点击某一个链接的时候,该页面并不是直接刷新,而是新建了一个页面,所以我们需要跳转到新的页面去提取有效的信息,如果是requests方法提取信息,我们一搬观察新开的页面与之前页面的关系,通过构造连接的方式,找到新页面的url,并向新的url发送请求。

对于selenium,我们仍然可以采用相同的方式,但是selenium也提供了一种切换窗口的方法,这里只做一个简单介绍。

在selenium眼中,新窗口默认是切换不过来的,只有通过web.switch_to.window(web.window_handles[-1]) 即跳转到当前浏览器任务栏中的最后一个handle,一般来说,新的handle都是在最后一个。

通过web.close()就可以关闭窗口,如果你使用了窗口切换的话,说明关掉的就是新页面,然后通过web.switch_to.window()就可以切换handles了。

下面仍然是以拉勾网为例,通过窗口切换,并打印新窗口中的工作详情信息。

具体代码如下:

from selenium.webdriver import Chrome
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.common.by import By
import time
# 创建浏览器
web = Chrome()
# 打开一个网址
web.get("http://lagou.com")
# 找到某个元素,点击它
web.find_element(By.XPATH, '//*[@id="cboxClose"]').click()
time.sleep(1)  # 让浏览器缓一会儿
web.find_element(By.XPATH, '//*[@id="search_input"]').send_keys("python", Keys.ENTER)
time.sleep(1)
h3 = web.find_element(By.XPATH, '//*[@id="s_position_list"]/ul/li[1]/div[1]/div[1]/div[1]/a/h3')
web.execute_script("arguments[0].click();", h3)
# 如何进入到新窗口进行提取
# 在selenium眼中,新窗口默认切换不过来
web.switch_to.window(web.window_handles[-1])  # window_handles[-1]即窗口选项卡的最后一个
# 新窗口中提取内容
job_detail = web.find_element(By.XPATH, '//*[@id="job_detail"]/dd[2]/div').text
print(job_detail)
# 关掉子窗口
web.close()
# 变更selenium的窗口视角,回到原来的窗口中
web.switch_to.window(web.window_handles[0])
print(h3.text)

遇到iframe的情况

接下来将讲解使用selenium遇到iframe的情况。

首先,我们需要了解iframe到底是什么?

iframe是嵌入式框架, 是html标签, 也是一个内联元素, iframe 元素会创建包含另外一个文档的内联框架(即行内框架) 。简单来说,iframe就是在一个网页里内嵌了其他的页面。

iframe的使用:通过iframe标签并指定src即可。

 <iframe src="demo_iframe_sandbox.htm"></iframe> 

iframe的优缺点:

页面和程序分离,几乎不会受到外界任何js或者css的影响, 便于使用

可以通过iframe嵌套通用的页面, 提高代码的重用率, 比如页面的头部样式和底部版权信息**

重新加载页面时, 不需要重载iframe框架页的内容, 增加页面重载速度.

iframe可以解决第三方内容加载缓慢的问题.

会产生很多页面,不容易管理

iframe框架的内容无法被搜索引擎捕获, 所以iframe不适用于首页

iframe兼容性较差

iframe有一定的安全风险

iframe会阻塞主页面的Onload事件

所以要处理iframe话,需要先找到iframe,即通过xpath,或者selector等其他方法找到iframe标签,使用web.switch_to.frame()方法即可跳转到内嵌的iframe页面中。如果需要切换回原来的页面,使用web.switch_to.default_content()方法即可。

一般在视频网站可能出现iframe标签。

使用的框架大致如下:

from selenium.webdriver import Chrome
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.common.by import By
import time
# 创建浏览器
web = Chrome()
# 页面遇到iframe
web.get("https://www.91kanju.com/vod-play/541-1-2.html")
# 处理iframe话,需要先找到iframe
iframe = web.find_element(By.XPATH, '//*[@id="player_iframe"]')
web.switch_to.frame(iframe)
web.switch_to.default_content() # 切换为原页面
tx = web.find_element(By.XPATH, '//*[@id="main"]/h3[1]').text
print(tx)

很有可能代码中连接失效或者打不开了,没办法尝试,这时候你只需要知道有这种方法即可,下次遇到了相似的额页面,会使用就行。

前面介绍了那么多,我们使用selenium运行多次的话就会发现,他每运行一次就会新开一个浏览器,这对与win11系统来说并不友好。(毕竟本来就把开始菜单移到了中间,结果在是用啥selenium的话,又没有即时关闭窗口,就很容易造成任务挤死的情况

有什么方法能够让我们的任务栏看起来清爽呢?

当然是headless --- 无头浏览器了!

headless(无头浏览器)

headless:不需要为操作者演示运行过程,只需要返回结果即可

headless是一个配置参数,在实例化一个Chrome对象之前,就需要把参数设置好。 具体参数如下

# 准备好参数配置
opt = Options()
opt.add_argument("--headless")
opt.add_argument("--disable-gpu")

配置好了参数之后,只需要创建浏览器并且将参数配置进去就好。

web = Chrome(options=opt)

小demo,for example:

from selenium.webdriver import Chrome
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.support.select import Select
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.common.by import By
import time
# 准备好参数配置
opt = Options()
opt.add_argument("--headless")
opt.add_argument("--disable-gpu")
# 创建浏览器并且将参数配置进去
web = Chrome(options=opt)
web.get("https://ys.endata.cn/BoxOffice/Ranking")
table = web.find_element(By.XPATH, '//*[@id="app"]/section/main/div/div[1]/div/section/section/section/section/div[1]/div[3]/table')
print(table.text)
如果有下拉选项
# 定位到下拉列表
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('xxxxxxx')  
# 拿到页面代码Elements(经过数据加载以及js执行之后的结果html内容)
print(web.page_source)

还有些网站是不允许用户使用selenium爬取的,这时候我们可以尝试配置另外一个参数防止程序被识别,具体参数如下:

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

little demo

目标:12306网站

操作:模拟输入用户名和密码

代码如下:

from selenium.webdriver import Chrome
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.common.action_chains import ActionChains
from selenium.webdriver.common.by import By
import time
# 程序被识别了怎么办?
opt = Options()
opt.add_argument('--disable-blink-features=AutomationControlled')
web = Chrome(options=opt)
web.get("https://kyfw.12306.cn/otn/resources/login.html")
time.sleep(2)
web.find_element(By.XPATH, '//*[@id="toolbar_Div"]/div[2]/div[2]/ul/li[2]/a').click()
time.sleep(3)
# 向页面中填入用户名,密码,验证码
web.find_element(By.XPATH, '//*[@id="J-userName"]').send_keys("xxx")
web.find_element(By.XPATH, '//*[@id="J-password"]').send_keys("xxx")
time.sleep(5)
# 点击登录
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(60)

本次的文章就暂且码到这儿了⛷️⛷️⛷️,如果对你有帮助的话,就点个,几天后继续更新~

往期好文推荐🪶

「MongoDB」Win10版安装教程

「Python」数字推盘游戏

「Python」sklearn第一弹-标准化和非线性转化

「Python」turtle绘制图形🎈

「Python」Pandas-DataFrame的相关操作二

xincheng_q
粉丝