崔庆才老师爬虫的学习笔记。
一、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() 
 
持续更新…