Toggle navigation
直到世界的尽头
主页
搜索
python--爬虫--最全selenium的常用方法收集
计算机相关
2021-12-07 18:26:19.0
# selenium的基本使用 ``` from selenium import webdriver # 用来驱动浏览器的 from selenium.webdriver import ActionChains # 破解滑动验证码的时候用的 可以拖动图片 from selenium.webdriver.common.by import By # 按照什么方式查找,By.ID,By.CSS_SELECTOR from selenium.webdriver.common.keys import Keys # 键盘按键操作 from selenium.webdriver.support import expected_conditions as EC # 和下面WebDriverWait一起用的 from selenium.webdriver.support.wait import WebDriverWait # 等待页面加载某些元素 import time driver=webdriver.Chrome() try: wait=WebDriverWait(driver,10) #1、访问百度 driver.get('https://www.baidu.com/') #2、查找输入框 input_tag=wait.until(EC.presence_of_element_located((By.ID,"kw"))) #3、在搜索框在输入要搜索的内容 input_tag.send_keys('张小凡') # 4、按键盘回车键 input_tag.send_keys(Keys.ENTER) time.sleep(3) finally: driver.close() ``` # 浏览器控制相关操作函数 访问页面 ``` driver.get('https://www.zhihu.com') #访问知乎 ``` 设置浏览器窗口大小: ``` driver.set_window_size(480, 800) ``` 回退到上一个访问页面: ``` driver.back() ``` 前进到下一个访问页面: ``` driver.forward() ``` 退出浏览器 ``` drive.quit() ``` 关闭单个窗口 ``` drive.close() ``` 浏览器窗口最大化 ``` driver.maximize_window() ``` # 定位操作 打开页面后我们获取数据肯定是需要定位到具体的元素,所以定位是很常用的操作 ``` find_element_by_id() #通过id查找获取 find_element_by_name() #通过name属性查找 find_element_by_class_name() #通过class属性查找 find_element_by_tag_name() #通过标签名字查抄 find_element_by_link_text() #通过浏览器中可点击的文本查找 find_element_by_xpath() #通过xpath表达式查找 find_element_by_css_selector() #通过css选择器查找 ``` 具体示例 ``` driver=webdriver.Chrome() #实例化一个浏览器 driver.get('https://www.baidu.com') #浏览器访问百度 input_tag=driver.find_element_by_id('kw') #获取输入框 input_tag.send_keys('赵丽颖')#输入框中输入'赵丽颖 driver.find_element_by_id('su').click() #找到’百度一下'按钮,并点击,开始搜索 driver.find_element_by_link_text('知道').click() #点击页面上的 ’知道' ``` 其他常用查找 ``` # 根据xpath语法查找元素 # / 从根节点开始找第一个 html = driver.find_element_by_xpath('/html') # html = driver.find_element_by_xpath('/head') # 报错 print(html.tag_name) # // 从根节点开始找任意一个节点 div = driver.find_element_by_xpath('//div') print(div.tag_name) # @ # 查找id为images的div节点 div = driver.find_element_by_xpath('//div[@id="images"]') print(div.tag_name) print(div.text) # 找到第一个a节点 a = driver.find_element_by_xpath('//a') print(a.tag_name) # 找到所有a节点 a_s = driver.find_elements_by_xpath('//a') print(a_s) # 找到第一个a节点的href属性 # get_attribute:获取节点中某个属性 a = driver.find_element_by_xpath('//a').get_attribute('href') print(a) ``` # 获取属性 size和文本 ``` driver.title #返回当前页面的标题 driver.current_url #返回当前页面的url print(driver.current_url) # 打印出当前网页的url print(driver.page_source) # 打印网页的源码 driver.find_element_by_id('kw').size #获取搜索的元素的尺寸{'height’: 22, 'width’: 395} driver.find_element_by_id('cp').text #获取指定标签的文本值 #获取图片中的a标签文本信息 a_list=driver.find_elements_by_xpath('//div[@id="u1"]/a') for a in a_list: print(a.text) print(driver.get_cookies()) # 打印出网页的cookie ``` # frame切换 有时候我们用selenium获取到的数据会遇到所见非所得,或者定位页面元素的时候会定位不到的问题,这种情况很有可能是frame的问题,必须切换到相应frame中再进行定位。 如果遇到以上问题,第一时间F12看下你所要的信息是否在frame标签里面。 frame标签有frameset、frame、iframe三种,frameset跟其他普通标签没有区别,不会影响到正常的定位,而frame与iframe对selenium定位而言是一样的。 selenium提供了4种方法定位iframe并切换进去: ``` driver.switch_to_frame(0) # 用frame的index来定位,第一个是0,以此类推 driver.switch_to_frame("frame1") # 用id来定位 driver.switch_to_frame("dark") # 用name来定位 driver.switch_to_frame(driver.find_element_by_tag_name("iframe")) # 用WebElement对象来定位 ``` 通常通过id和name就能实现,无此属性时可以通过WebElement对象,即用find_element系列方法所取得的对象来定位。如果你确定每个目标frame都是固定第几个,那也可以用index定位 切到frame中之后,就不能继续操作主文档的元素了,这时如果想操作主文档内容,则需切回主文档。 ``` driver.switch_to_default_content() ``` # 嵌套frame的切换 如果frame里包着frame,而你要的frame是后者,那么需要一层一层切换进去,切换方法四选一 ``` driver.switch_to_frame("frame1") driver.switch_to_frame("frame2") ``` 如果想回去上一个父frame,用 ``` driver.switch_to.parent_frame() ``` # window 切换 有时候点开一个链接就会弹出一个新窗口,如果要对其操作就要切换过去,方法和frame的切换差不多,但只接收window_handle(相当于窗口的名字)来进行切换 ``` driver.switch_to_window("windowName") ``` 切换前最好保存之前的handle和所有的handles以便于来回切换。 ``` current_window = driver.current_window_handle # 获取当前窗口handle name all_windows = driver.window_handles # 获取所有窗口handle name # 如果window不是当前window,则切换到该window,即切换到新窗口 for window in all_windows: if window != current_window: driver.switch_to_window(window) #.... driver.switch_to_window(current_window) # 返回之前的窗口 driver.close() # 窗口的关闭用close() ``` # 是否开启无头模式(即是否需要界面) ``` from selenium.webdriver import Chrome from selenium.webdriver.chrome.options import Options option = Options() # 实例化option对象 option.add_argument("--headless") # 给option对象添加无头参数 driver = Chrome(executable_path=r"E:\python学习\python爬虫\chromedriver.exe", options=option) # 实例化浏览器对象,可以指定chromedriver的路径,不指定的话 默认会去找python解释器的同级目录 # 实例化浏览器对象的时候 把option对象带进来 ``` # 鼠标事件 在 WebDriver 中, 将这些关于鼠标操作的方法封装在 ActionChains 类提供。 ``` perform():执行所有ActionChains中存储的所有行为 context_click():右击 double_click():双击 drag_and_drop():拖动 click(on_element=None) ——单击鼠标左键 click_and_hold(on_element=None) ——点击鼠标左键,不松开 context_click(on_element=None) ——点击鼠标右键 double_click(on_element=None) ——双击鼠标左键 drag_and_drop(source, target) ——拖拽到某个元素然后松开 drag_and_drop_by_offset(source, xoffset, yoffset) ——拖拽到某个坐标然后松开 key_down(value, element=None) ——按下某个键盘上的键 key_up(value, element=None) ——松开某个键 move_by_offset(xoffset, yoffset) ——鼠标从当前位置移动到某个坐标 move_to_element(to_element) ——鼠标移动到某个元素 move_to_element_with_offset(to_element, xoffset, yoffset) ——移动到距某个元素(左上角坐标)多少距离的位置 release(on_element=None) ——在某个元素位置松开鼠标左键 send_keys(*keys_to_send) ——发送某个键到当前焦点的元素 send_keys_to_element(element, *keys_to_send) ——发送某个键到指定元素 ``` 使用示例 ``` #引入 ActionChains类 from selenium.webdriver.common.action_chains import ActionChains driver=webdriver.Chrome() driver.get('https://www.baidu.cn') #鼠标定位到需要悬浮的元素 above=driver.find_element_by_link_text('设置') ditu=driver.find_element_by_link_text('地图') #对定位的元素执行鼠标操作 ActionChains(driver).move_to_element(above).perform() ActionChains(driver).double_click(above).perform() #鼠标右击 driver.quit() #退出 ``` # 键盘事件 使用示例 ``` #引入Keys模块 from selenium.webdriver.common.keys import Keys driver=webdriver.Chrome() driver.get('https://www.baidu.com') #输入一个内容 input=driver.find_element_by_id('kw') input.send_keys('seleniumGG') #删除多余的GG input.send_keys(Keys.BACKSPACE) input.send_keys(Keys.BACKSPACE) #继续输入 input.send_keys('教程') 输入框清除 input.clear() #全选输入框的内容,一次性删除 input.send_keys(Keys.CONTROL,'a') # 全选 input.send_keys(Keys.BACKSPACE) #输入周杰伦,通过回车键来代替点击’百度一下’ input.send_keys('张小凡') input.send_keys(Keys.ENTER) driver.quit() ``` # 登录操作 登录示例一 ``` from selenium import webdriver driver = webdriver.Chrome() driver.get('http://www.renren.com/') #输入账户密码 driver.find_element_by_id('email').send_keys('123') #换成自己的账号 driver.find_element_by_id('password').send_keys('123') #换成自己的密码 #点击登录 driver.find_element_by_id('login').click() driver.quit() ``` 登录示例二 ``` from selenium import webdriver # 用来驱动浏览器的 import time driver = webdriver.Chrome() try: # 往百度发送请求 driver.get('https://www.baidu.com/') driver.implicitly_wait(10) # 1、find_element_by_link_text 通过链接文本去找 # 根据登录 # send_tag = driver.find_element_by_link_text('登录') # send_tag.click() # 2、find_element_by_partial_link_text 通过局部文本查找a标签 login_button = driver.find_element_by_partial_link_text('登录') login_button.click() time.sleep(1) # 3、find_element_by_class_name 根据class属性名查找 login_tag = driver.find_element_by_class_name('tang-pass-footerBarULogin') login_tag.click() time.sleep(1) # 4、find_element_by_name 根据name属性查找 username = driver.find_element_by_name('userName') username.send_keys('15622792660') time.sleep(1) # 5、find_element_by_id 通过id属性名查找 password = driver.find_element_by_id('TANGRAM__PSP_10__password') password.send_keys('*******') time.sleep(1) # 6、find_element_by_css_selector 根据属性选择器查找 # 根据id查找登录按钮 login_submit = driver.find_element_by_css_selector('#TANGRAM__PSP_10__submit') # driver.find_element_by_css_selector('.pass-button-submit') login_submit.click() # 7、find_element_by_tag_name 根据标签名称查找标签 div = driver.find_element_by_tag_name('div') print(div.tag_name) time.sleep(10) finally: driver.close() ``` # 警告框的处理 基本方法 ``` accept():接受现有警告框。 dismiss():解散现有警告框。 send_keys(keysToSend):发送文本至警告框。keysToSend:将文本发送至警告框。 ``` 使用示例 ``` #获取警告框对象 dialog=driver.switch_to_alert() dialog.text #获取警告框的内容 dialog.accept() #接受结果,确认 driver.quit() ``` # 下拉框选择 ``` #核心代码 from selenium.webdriver.support.select import Select #搜索结果显示条数设置 sel=driver.find_element_by_xpath('//[@id=”nr”]') Select(sel).select_by_value('10') ``` 使用示例 ``` #第一步导包 from selenium import webdriver from selenium.webdriver.support.select import Select from time import sleep #驱动网页 driver = webdriver.Chrome() driver.implicitly_wait(10) driver.get('http://www.baidu.com') # 鼠标悬停至'设置”链接 driver.find_element_by_link_text('设置').click() sleep(1) # 打开搜索设置 driver.find_element_by_link_text('搜索设置').click() sleep(2) #搜索结果显示条数设置 sel=driver.find_element_by_xpath('//[@id=”nr”]') Select(sel).select_by_value('10') #保存并关闭 driver.find_element_by_class_name('prefpanelgo').click() #处理警告框 #1 获取警告框对象 dialog=driver.switch_to_alert() #2 打印文本值 print(dialog.text) #已经记录下您的使用偏好 #3 接受 dialog.accept() driver.quit() ``` # 文件上传 定位上传按钮,添加本地文件 ``` driver.find_element_by_name('file').send_keys('D:\upload_file.txt') ``` # cookie操作 ``` get_cookies(): 获得所有cookie信息。 get_cookie(name): 返回字典的key为'name'的cookie信息。 add_cookie(cookie_dict) : 添加cookie。'cookie_dict'指字典对象,必须有name 和value 值。 delete_cookie(name,optionsString):删除cookie信息。'name'是要删除的cookie的名称,'optionsString;是该cookie的选项,目前支持的选项包括'路径','域'。 delete_all_cookies(): 删除所有cookie信息。 ``` 使用示例 ``` cookie= driver.get_cookies() #获取cookie driver.add_cookie({'name': 'key-aaaaaaa', 'value': 'value-bbbbbb'}) #添加cookie ``` # 调用JavaScript代码 ```` window.scrollTo(0,450); #滑动条往下滑动450 # 执行方式 js="window.scrollTo(100,450);" driver.execute_script(js) js='window.scrollTo(0,document.body.scrollHeight)' #下滑到底部 driver.execute_script(js) ``` # 窗口截图 截取当前窗口,并指定截图图片的保存位置 ``` driver.get_screenshot_as_file('D:\baidu_img.jpg') ``` # 页面等待--等待元素被加载 selenium只是模拟浏览器的行为,而浏览器解析页面是需要时间的(执行css,js),一些元素可能需要过一段时间才能加载出来,为了保证所有元素都能查到,必须等待。 ``` # time.sleep(1) time.sleep(random.uniform(4,5)) from selenium import webdriver from selenium.webdriver.support import expected_conditions as EC from selenium.webdriver.common.by import By 6 from selenium.webdriver.support.wait import WebDriverWait #等待页面加载某些元素 driver=webdriver.Chrome() # 隐式等待:在browser.get('xxx')之前设置,针对所有元素有效 driver.implicitly_wait(5) #隐式等待:在查找所有元素时,如果尚未被加载,则等10秒 # 显式等待:在browser.get('xxx')之后设置,只针对某个元素有效 #显式等待:显式地等待某个元素被加载 wait=WebDriverWait(browser,10) wait.until(EC.presence_of_element_located((By.ID,'content_left'))) contents=browser.find_element(By.CSS_SELECTOR,'#content_left') print(contents) ``` # 滑动界面 ``` from selenium import webdriver driver=webdriver.Chrome() js = "document.documentElement.scrollTop=800" # 执行js driver.execute_script(js) time.sleep(1) # 滚动到顶部 js = "document.documentElement.scrollTop=0" driver.execute_script(js) # 执行js ``` # ActionChangs动作链--移动--点击--摁住--拖拽 ``` from selenium import webdriver from selenium.webdriver import ActionChains import time driver = webdriver.Chrome() driver.implicitly_wait(10) driver.get('http://www.runoob.com/try/try.php?filename=jqueryui-api-droppable') try: # driver.switch_to_frame('iframeResult') # 切换到id为iframeResult的窗口内 driver.switch_to.frame('iframeResult') # 源位置 draggable = driver.find_element_by_id('draggable') # 目标位置 droppable = driver.find_element_by_id('droppable') # 调用ActionChains,必须把驱动对象传进去 # 得到一个动作链对象,复制给一个变量 actions = ActionChains(driver) # 方式一: 机器人 # 瞬间把源图片位置秒移到目标图片位置 # actions.drag_and_drop(draggable, droppable) # 编写一个行为 # actions.perform() # 执行编写好的行为 # 方式二: 模拟人的行为 source = draggable.location['x'] target = droppable.location['x'] print(source, target) distance = target - source print(distance) # perform:每个动作都要调用perform执行 # 点击并摁住源图片 ActionChains(driver).click_and_hold(draggable).perform() s = 0 while s < distance: # 执行位移操作 ActionChains(driver).move_by_offset(xoffset=2, yoffset=0).perform() s += 2 # 释放动作链 ActionChains(driver).release().perform() time.sleep(10) finally: driver.close() ``` # 扩展程序加载 ``` # 设置好应用扩展 chrome_options.add_extension(extension_path) #添加下载路径 #download.default_directory:设置下载路径 profile.default_content_settings.popups:设置为 0 禁止弹出窗口 prefs = {'profile.default_content_settings.popups': 0, 'download.default_directory':tmp_path} chrome_options.add_experimental_option('prefs', prefs) ``` # 滑块处理 https://www.cnblogs.com/jackzz/p/11443193.html https://blog.csdn.net/weixin_43977603/article/details/105768270 https://blog.csdn.net/weixin_39823751/article/details/114691611 # 可能遇到的问题--被识别为爬虫反爬 解决方案参考: ## 方案一 如何规避网站对selenium检测的风险 现在不少大网站对使用selenium爬虫采取了检测机制,比如正常情况下,我们用浏览器访问淘宝等网站的window.navigator.webdriver的值为undefined,而使用selenium访问则为true,那么如何解决这个问题呢?只要设置Chromedriver的启动参数就可以解决问题。 from selenium.webdriver import Chrome from selenium.webdriver import ChromeOptions driver_path = r'D:\Learn\chromedriver_win32\chromedriver.exe' option = ChromeOptions() option.add_experimental_option('excludeSwitches', ['enable-automation']) driver = Chrome(options=option) browser = webdriver.Chrome(executable_path=driver_path, options=option) ## 方案二 解决方法就是手动打开浏览器,然后用selenium控制这个浏览器跑程序。 cmd 运行命令chrome.exe --remote-debugging-port=9222 打开一个浏览器 然后py代码里 ``` chrome_options.add_experimental_option("debuggerAddress", "127.0.0.1:9222") ``` 添加一个这个Options。其它的代码不变 https://www.zhihu.com/question/50738719 # 更多文档 https://selenium-python-docs-zh.readthedocs.io/zh_CN/latest/ https://github.com/SeleniumHQ/selenium https://selenium-python-zh.readthedocs.io/en/latest/index.html https://www.selenium.dev/selenium/docs/api/py/api.html