崔庆才老师爬虫的学习笔记。
一、Selenium库详解 1、什么是Selenium Selenium是一个自动化测试工具,利用它可以驱动浏览器执行特定的动作,如点击、下拉等操作,同时还可以获取浏览器当前呈现的页面的源代码,做到可见即可爬。对于一些JavaScript动态渲染的页面来说,此种抓取方式非常有效。
2、安装 pip install selenium
3、基本使用 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 from selenium import webdriverfrom selenium.webdriver.common.by import Byfrom selenium.webdriver.common.keys import Keysfrom selenium.webdriver.support import expected_conditions as ECfrom selenium.webdriver.support.wait import WebDriverWaitbrowser = webdriver.Chrome() try : browser.get('https://www.baidu.com' ) input = browser.find_element_by_id('kw' ) input.send_keys('python' ) input.send_keys(Keys.ENTER) wait = WebDriverWait(browser,10 ) wait.until(EC.presence_of_element_located((By.ID,'content_left' ))) print(browser.current_url) print(browser.get_cookies()) print(browser.page_source) finally : browser.close()
4、声明浏览器对象 Selenium支持非常多的浏览器,如Chrome、Firefox、Edge等,还有Android、BlackBerry等手机端的浏览器。另外,也支持无界面浏览器PhantomJS。
1 2 3 4 5 6 7 from selenium import webdriver browser = webdriver.Chrome() browser = webdriver.Firefox() browser = webdriver.Edge() browser = webdriver.PhantomJS() browser = webdriver.Safari()
5、访问页面 1 2 3 4 5 6 from selenium import webdriverbrowser = webdriver.Chrome() browser.get('https://www.taobao.com' ) print(browser.page_source) browser.close()
6、查找节点 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 from selenium import webdriverfrom selenium.webdriver.common.by import Bybrowser = webdriver.Chrome() browser.get('https://www.taobao.com' ) input1 = browser.find_element_by_id('q' ) input2 = browser.find_element_by_css_selector('#q' ) input3 = browser.find_element_by_xpath('//*[@id="q"]' ) print(input1,input2,input3) input1_same = browser.find_element(By.ID,'q' ) print(input1_same) browser.close()
所有获取单个节点的方法:
find_element_by_id
find_element_by_name
find_element_by_xpath
find_element_by_link_text
find_element_by_partial_link_text
find_element_by_tag_name
find_element_by_class_name
find_element_by_css_selector
1 2 3 4 5 6 7 8 9 10 11 12 13 from selenium import webdriverbrowser = webdriver.Chrome() browser.get('https://www.taobao.com' ) lis = browser.find_elements_by_css_selector('.service-bd li' ) print(lis) lis_same = browser.find_elements(By.CSS_SELECTOR,'.service-bd li' ) print(lis_same) browser.close()
所有获取多个节点的方法:
find_elements_by_id
find_elements_by_name
find_elements_by_xpath
find_elements_by_link_text
find_elements_by_partial_link_text
find_elements_by_tag_name
find_elements_by_class_name
find_elements_by_css_selector
7、元素交互 官方文档:http://selenium-python.readthedocs.io/api.html#module-selenium.webdriver.remote.webelement
1 2 3 4 5 6 7 8 9 10 11 12 13 14 from selenium import webdriverimport timebrowser = webdriver.Chrome() browser.get('https://www.taobao.com' ) input = browser.find_element_by_id('q' ) input.send_keys('iphone' ) time.sleep(1 ) input.clear() input.send_keys('ipad' ) button = browser.find_element_by_class_name('btn-search' ) button.click() time.sleep(3 ) browser.close()
8、交互动作(动作链) 还有一些操作,它们没有特定的执行对象,比如鼠标拖曳、键盘按键等,这些动作用另一种方式来执行,那就是动作链。
将动作附加到动作链中串行执行。
官方文档:http://selenium-python.readthedocs.io/api.html#module-selenium.webdriver.common.action_chains
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 from selenium import webdriverfrom selenium.webdriver import ActionChainsimport timebrowser = webdriver.Chrome() browser.get('http://www.runoob.com/try/try.php?filename=jqueryui-api-droppable' ) time.sleep(5 ) browser.switch_to.frame('iframeResult' ) source = browser.find_element_by_css_selector('#draggable' ) target = browser.find_element_by_css_selector('#droppable' ) actions = ActionChains(browser) actions.drag_and_drop(source,target) actions.perform() time.sleep(3 ) browser.close()
9、执行JavaScript 对于某些操作,Selenium API并没有提供。比如,下拉进度条,它可以直接模拟运行JavaScript,此时使用execute_script()方法即可实现。
1 2 3 4 5 6 7 8 9 from selenium import webdriverimport timebrowser = webdriver.Chrome() browser.get('https://www.zhihu.com/explore' ) browser.execute_script('window.scrollTo(0,document.body.scrollHeight)' ) browser.execute_script('alert("To Bottom")' ) time.sleep(3 ) browser.close()
10、获取元素信息 Selenium已经提供了选择节点的方法,返回的是WebElement类型,那么它也有相关的方法和属性来直接提取节点信息,如属性、文本等。这样的话,我们就可以不用通过解析源代码来提取信息了,非常方便。
1 2 3 4 5 6 7 8 9 10 11 12 from selenium import webdriverimport timebrowser = webdriver.Chrome() browser.get('https://www.zhihu.com/explore' ) logo = browser.find_element_by_id('zh-top-link-logo' ) print(logo) print(logo.get_attribute('class' )) time.sleep(3 ) browser.close()
1 2 3 4 5 6 7 8 9 10 11 12 from selenium import webdriverimport timebrowser = webdriver.Chrome() browser.get('https://www.zhihu.com/explore' ) input = browser.find_element_by_class_name('zu-top-add-question' ) print(input) print(input.text) time.sleep(3 ) browser.close()
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 from selenium import webdriverimport timebrowser = webdriver.Chrome() browser.get('https://www.zhihu.com/explore' ) input = browser.find_element_by_class_name('zu-top-add-question' ) print(input) print(input.id) print(input.location) print(input.tag_name) print(input.size) time.sleep(3 ) browser.close()
11、切换Frame 网页中有一种节点叫作iframe,也就是子Frame,相当于页面的子页面,它的结构和外部网页的结构完全一致。Selenium打开页面后,它默认是在父级Frame里面操作,而此时如果页面中还有子Frame,它是不能获取到子Frame里面的节点的。这时就需要使用switch_to.frame()方法来切换Frame。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 from selenium import webdriverfrom selenium.common.exceptions import NoSuchElementExceptionimport timebrowser = webdriver.Chrome() browser.get('http://www.runoob.com/try/try.php?filename=jqueryui-api-droppable' ) browser.switch_to.frame('iframeResult' ) try : logo = browser.find_element_by_class_name('logo' ) except NoSuchElementException: print('NO LOGO' ) browser.switch_to.parent_frame() logo = browser.find_element_by_class_name('logo' ) print(logo) print(logo.text) time.sleep(3 ) browser.close()
12、延时等待 这里等待的方式有两种:一种是隐式等待,一种是显式等待。
隐式等待,如果Selenium没有在DOM中找到节点,将继续等待,超出设定时间后,则抛出找不到节点的异常。隐式等待的效果其实并没有那么好,因为我们只规定了一个固定时间,而页面的加载时间会受到网络条件的影响。
显式等待,它指定要查找的节点,然后指定一个最长等待时间。如果在规定时间内加载出来了这个节点,就返回查找的节点;如果到了规定时间依然没有加载出该节点,则抛出超时异常。
1 2 3 4 5 6 7 8 9 10 from selenium import webdriverbrowser = webdriver.Chrome() browser.implicitly_wait(10 ) browser.get('https://www.zhihu.com/explore' ) input = browser.find_element_by_class_name('zu-top-add-question' ) print(input) browser.close()
1 2 3 4 5 6 7 8 9 10 11 12 13 from selenium import webdriverfrom selenium.webdriver.common.by import Byfrom selenium.webdriver.support.ui import WebDriverWaitfrom selenium.webdriver.support import expected_conditions as ECbrowser = webdriver.Chrome() browser.get('https://www.taobao.com/' ) wait = WebDriverWait(browser,10 ) input = wait.until(EC.presence_of_element_located((By.ID,'q' ))) button = wait.until(EC.element_to_be_clickable((By.CSS_SELECTOR,'.btn-search' ))) print(input,button) browser.close()
等待条件及其含义:
title_is
:标题是某内容
title_contains
:标题包含某内容
presence_of_element_located
:节点加载出来,传入定位元组,如(By.ID, ‘p’)
visibility_of_element_located
:节点可见,传入定位元组
visibility_of
:可见,传入节点对象
presence_of_all_elements_located
:所有节点加载出来
text_to_be_present_in_element
:某个节点文本包含某文字
text_to_be_present_in_element_value
:某个节点值包含某文字
frame_to_be_available_and_switch_to_it
:加载并切换
invisibility_of_element_located
:节点不可见
element_to_be_clickable
:节点可点击
staleness_of
:判断一个节点是否仍在DOM,可判断页面是否已经刷新
element_to_be_selected
:节点可选择,传节点对象
element_located_to_be_selected
:节点可选择,传入定位元组
element_selection_state_to_be
:传入节点对象以及状态,相等返回True,否则返回False
element_located_selection_state_to_be
:传入定位元组以及状态,相等返回True,否则返回False
alert_is_present
:是否出现警告
等待条件的参数及用法参考官方文档:http://selenium-python.readthedocs.io/api.html#module-selenium.webdriver.support.expected_conditions
13、前进后退 1 2 3 4 5 6 7 8 9 10 11 12 13 from selenium import webdriverimport timebrowser = webdriver.Chrome() browser.get('https://www.baidu.com/' ) browser.get('https://www.taobao.com/' ) browser.get('https://www.python.org/' ) browser.back() time.sleep(2 ) browser.forward() time.sleep(2 ) browser.close()
14、Cookies Selenium可以方便地对Cookies进行操作,例如获取、添加、删除Cookies等
1 2 3 4 5 6 7 8 9 10 from selenium import webdriver browser = webdriver.Chrome() browser.get('https://www.zhihu.com/explore' ) print(browser.get_cookies()) browser.add_cookie({'name' : 'name' , 'domain' : 'www.zhihu.com' , 'value' : 'germey' }) print(browser.get_cookies()) browser.delete_all_cookies() print(browser.get_cookies()) browser.close()
15、选项卡管理 在访问网页的时候,会开启一个个选项卡。Selenium也可以对选项卡进行操作。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 from selenium import webdriverimport time browser = webdriver.Chrome() browser.get('https://www.baidu.com' ) browser.execute_script('window.open()' ) print(browser.window_handles) browser.switch_to_window(browser.window_handles[1 ]) browser.get('https://www.taobao.com' ) time.sleep(2 ) browser.switch_to_window(browser.window_handles[0 ]) browser.get('https://python.org' ) time.sleep(2 ) browser.close()
16、异常处理 官方文档:http://selenium-python.readthedocs.io/api.html#module-selenium.common.exceptions
1 2 3 4 5 from selenium import webdriver browser = webdriver.Chrome() browser.get('https://www.baidu.com' ) browser.find_element_by_id('hello' )
1 2 3 4 5 6 7 8 9 10 11 12 13 14 from selenium import webdriverfrom selenium.common.exceptions import TimeoutException,NoSuchElementExceptionbrowser = webdriver.Chrome() try : browser.get('https://www.baidu.com' ) except TimeoutException: print('Time Out' ) try : browser.find_element_by_id('hello' ) except NoSuchElementException: print('No Element' ) finally : browser.close()
持续更新…