zoukankan      html  css  js  c++  java
  • 爬虫之selenium模块

    一介绍

    selenium最初是一个自动化测试工具,而爬虫中使用它主要是为了解决requests无法直接执行JavaScript代码的问题
    
    selenium本质是通过驱动浏览器,完全模拟浏览器的操作,比如跳转、输入、点击、下拉等,来拿到网页渲染之后的结果,可支持多种浏览器
    
    from selenium import webdriver
    browser=webdriver.Chrome()
    browser=webdriver.Firefox()
    browser=webdriver.PhantomJS()
    browser=webdriver.Safari()
    browser=webdriver.Edge()

    二安装

    #安装:selenium+chromedriver
    windows 安装
    pip3 install selenium
    下载chromdriver.exe放到python安装路径的scripts目录中即可,注意最新版本是2.29,并非2.9
    下载链接:http://npm.taobao.org/mirrors/chromedriver/2.29/
    
    Mac 安装
    python3.5 -m pip install selenium
    下载 chromedriver 64 位 mac版
    cp chromedriver /usr/local/bin/
    
    
    #验证安装
    C:UsersAdministrator>python3
    Python 3.6.1 (v3.6.1:69c0db5, Mar 21 2017, 18:41:36) [MSC v.1900 64 bit (AMD64)] on win32
    Type "help", "copyright", "credits" or "license" for more information.
    >>> from selenium import webdriver
    >>> driver=webdriver.Chrome() #弹出浏览器
    >>> driver.get('https://www.baidu.com')
    >>> driver.page_source
    >>> driver.close()
    
    #注意:
    selenium3默认支持的webdriver是Firfox,而Firefox需要安装geckodriver
    下载链接:https://github.com/mozilla/geckodriver/releases
    
    selenium+chromedriver
    selenium+chromedriver
    #安装:selenium+phantomjs
    windows安装
    pip3 install selenium
    下载phantomjs,解压后把phantomjs.exe所在的bin目录放到环境变量
    下载链接:http://phantomjs.org/download.html
    
    Mac安装
    python3.5 -m pip install selenium
    cp Phantomjs /usr/local/bin/
    Phantomjs下载地址
    http://phantomjs.org/download.html
    
    
    #验证安装
    C:UsersAdministrator>phantomjs
    phantomjs> console.log('egon gaga')
    egon gaga
    undefined
    phantomjs> ^C
    C:UsersAdministrator>python3
    Python 3.6.1 (v3.6.1:69c0db5, Mar 21 2017, 18:41:36) [MSC v.1900 64 bit (AMD64)] on win32
    Type "help", "copyright", "credits" or "license" for more information.
    >>> from selenium import webdriver
    >>> driver=webdriver.PhantomJS() #无界面浏览器
    >>> driver.get('https://www.baidu.com')
    >>> driver.page_source
    >>> driver.close()
    
    selenium+phantomjs
    selenium+phantomjs

    三基本使用

    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 #场景判断用的,一般和下面的等待加载元素一起使用
    from selenium.webdriver.support.wait import WebDriverWait #等待页面加载某些元素
    
    browser=webdriver.Chrome()
    try:
        browser.get('https://www.baidu.com')
    
        input_tag=browser.find_element_by_id('kw')
        input_tag.send_keys('美女') #python2中输入中文错误,字符串前加个u
        input_tag.send_keys(Keys.ENTER) #输入回车
    
        wait=WebDriverWait(browser,10)
    wait.until(EC.presence_of_element_located((By.ID,
    'content_left'))) #等到id为content_left的元素加载完毕,最多等10秒 print(browser.page_source) print(browser.current_url) print(browser.get_cookies()) finally: browser.close()

     四选择器

    1. 基本用法

    #官网链接:http://selenium-python.readthedocs.io/locating-elements.html
    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
    from selenium.webdriver.support.wait import WebDriverWait #等待页面加载某些元素
    import time
    
    driver=webdriver.Chrome()
    driver.get('https://www.baidu.com')
    wait=WebDriverWait(driver,10)
    
    try:
        #===============所有方法===================
        # 1、find_element_by_id    id 查找
        # 2、find_element_by_link_text   文本查找
        # 3、find_element_by_partial_link_text  模糊文本查找
        # 4、find_element_by_tag_name  标签名称查找
        # 5、find_element_by_class_name  类查找
        # 6、find_element_by_name  属性name查找
        # 7、find_element_by_css_selector css 查找
        # 8、find_element_by_xpath 如果上述还不够,可以用xpath一级一级查找
        # 强调:
        # 1、上述均可以改写成find_element(By.ID,'kw')的形式
        # 2、find_elements_by_xxx的形式是查找到多个元素,结果为列表
    
        #===============示范用法===================
        # 1、find_element_by_id
        print(driver.find_element_by_id('kw'))
    
        # 2、find_element_by_link_text
        # login=driver.find_element_by_link_text('登录')
        # login.click()
    
        # 3、find_element_by_partial_link_text
        login=driver.find_elements_by_partial_link_text('')[0]
        login.click()
    
        # 4、find_element_by_tag_name
        print(driver.find_element_by_tag_name('a'))
    
        # 5、find_element_by_class_name
        button=wait.until(EC.element_to_be_clickable((By.CLASS_NAME,'tang-pass-footerBarULogin')))
        button.click()
    
        # 6、find_element_by_name
        input_user=wait.until(EC.presence_of_element_located((By.NAME,'userName')))
        input_pwd=wait.until(EC.presence_of_element_located((By.NAME,'password')))
        commit=wait.until(EC.element_to_be_clickable((By.ID,'TANGRAM__PSP_10__submit')))
    
        input_user.send_keys('18611453110')
        input_pwd.send_keys('lhf@094573')
        commit.click()
    
        # 7、find_element_by_css_selector
        driver.find_element_by_css_selector('#kw')
    
        # 8、find_element_by_xpath
    
        time.sleep(5)
    
    finally:
        driver.close()
    View Code

    2. xpath

    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
    from selenium.webdriver.support.wait import WebDriverWait  # 等待页面加载某些元素
    import time
    
    try:
        driver = webdriver.Chrome()
        driver.implicitly_wait(3)
    
        driver.get('https://doc.scrapy.org/en/latest/_static/selectors-sample1.html')
    
        #1、//与/
         # 开头的//代表从整篇文档中寻找,开头是/代表最顶端,/html就是最顶端了
    
        tag=driver.find_element_by_xpath('/html/body/div/a')  # 一级一级的查找,遇到相同的找最近的
        print(tag.tag_name)  #  a
        print(tag.text)   #  Name: My image 1
        print(tag.get_attribute('href'))  #  获取属性
    
        tag=driver.find_elements_by_xpath('//a')  # 整篇文档中寻找查找所有的a标签
        print(tag)
    
        tag=driver.find_elements_by_xpath('//div//a') # 查找div下所有的a标签
        print(len(tag))
        tag=driver.find_elements_by_css_selector('div a')  # css选择器查找div下所有的a标签
        print(len(tag))
    
        #2、查找第几个,支持切片
        tag=driver.find_elements_by_xpath('//div//a[5]')
        print(tag[0].text)
    
        #3、按照属性查找
        tag1=driver.find_element_by_xpath('//a[@href="image4.html"]')   # a标签下href属性是image4.html的标签
        tag2=driver.find_element_by_xpath('//a[4]')   # 第四个
        tag3=driver.find_element_by_xpath('//a[contains(@href,"image4")]')  # contains 模糊匹配
    
        print(tag1.text)
        print(tag2.text)
        print(tag3.text)
    
        #4、其他
        # driver.find_elements_by_xpath('//*[@class="xxxxx"]')  # class是xxxxx的所有标签
        # driver.find_elements_by_xpath('//div[@class="xxxxx"][@class="yyyyy"]') # div下 有xxxxx属性还有yyyyy属性的所有标签
    
        print(driver.find_element_by_xpath('//a[img/@src="image2_thumb.jpg"]').text) # 子标签img属性src="image2_thumb.jpg的a标签
        print(driver.find_element_by_xpath('//a/..').tag_name) # 第一个a标签的父标签div
        print(driver.find_element_by_xpath('//a[2]/..').tag_name) # 第二个a标签的父标签div
    
        print([tag.tag_name for tag in driver.find_elements_by_xpath('//img//..')])  # 所有img标签的父标签a  ['a', 'a', 'a', 'a', 'a']
    
        img=driver.find_element_by_xpath('//img')
        print(img.location) # 位置  {'y': 31, 'x': 8}
        print(img.size) # 长宽 {'width': 16, 'height': 16}
    
        time.sleep(5)
    finally:
        driver.close()
    View Code

    3. 获取标签属性

    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
    from selenium.webdriver.support.wait import WebDriverWait #等待页面加载某些元素
    
    browser=webdriver.Chrome()
    
    browser.get('https://www.amazon.cn/')
    
    wait=WebDriverWait(browser,10)
    wait.until(EC.presence_of_element_located((By.ID,'cc-lm-tcgShowImgContainer')))
    
    tag=browser.find_element(By.CSS_SELECTOR,'#cc-lm-tcgShowImgContainer img')
    
    #获取标签属性,
    print(tag.get_attribute('src'))
    
    
    #获取标签ID,位置,名称,大小(了解)
    print(tag.id)
    print(tag.location)
    print(tag.tag_name)
    print(tag.size)
    
    
    browser.close()
    
    获取标签属性
    View Code

    五等待元素加载

    有的时候,你查找标签要对其操作的时候,因为页面没有加载过来,标签找不到

    #1、selenium只是模拟浏览器的行为,而浏览器解析页面是需要时间的(执行css,js),一些元素可能需要过一段时间才能加载出来,为了保证能查找到元素,必须等待
    
    #2、等待的方式分两种:
    隐式等待:在browser.get('xxx')前就设置,针对所有元素有效
    显式等待:在browser.get('xxx')之后设置,只针对某个元素有效
    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
    from selenium.webdriver.support.wait import WebDriverWait #等待页面加载某些元素
    
    browser=webdriver.Chrome()
    
    #隐式等待:在查找所有元素时,如果尚未被加载,则等10秒
    browser.implicitly_wait(10)
    
    browser.get('https://www.baidu.com')
    
    
    input_tag=browser.find_element_by_id('kw')
    input_tag.send_keys('美女')
    input_tag.send_keys(Keys.ENTER)
    
    contents=browser.find_element_by_id('content_left') #没有等待环节而直接查找,找不到则会报错
    print(contents)
    
    browser.close()
    
    隐式等待
    隐式等待
    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
    from selenium.webdriver.support.wait import WebDriverWait #等待页面加载某些元素
    
    browser=webdriver.Chrome()
    browser.get('https://www.baidu.com')
    
    
    input_tag=browser.find_element_by_id('kw')
    input_tag.send_keys('美女')
    input_tag.send_keys(Keys.ENTER)
    
    
    #显式等待:显式地等待某个元素被加载
    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)
    
    
    browser.close()
    显式等待

    六元素交互操作

    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
    from selenium.webdriver.support.wait import WebDriverWait #等待页面加载某些元素
    
    browser=webdriver.Chrome()
    browser.get('https://www.amazon.cn/')
    wait=WebDriverWait(browser,10)
    
    
    input_tag=wait.until(EC.presence_of_element_located((By.ID,'twotabsearchtextbox')))
    input_tag.send_keys('iphone 8')
    button=browser.find_element_by_css_selector('#nav-search > form > div.nav-right > div > input')
    button.click() 点击按钮
    
    
    import time
    time.sleep(3)
    
    input_tag=browser.find_element_by_id('twotabsearchtextbox')
    input_tag.clear() #清空输入框
    input_tag.send_keys('iphone7plus')  重新输入
    button=browser.find_element_by_css_selector('#nav-search > form > div.nav-right > div > input')
    button.click()
    
    
    
    # browser.close()
    
    点击,清空
    点击,清空
    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
    from selenium.webdriver.support.wait import WebDriverWait  # 等待页面加载某些元素
    import time
    
    driver = webdriver.Chrome()
    driver.get('http://www.runoob.com/try/try.php?filename=jqueryui-api-droppable')
    driver.implicitly_wait(3)  # 使用隐式等待
    
    try:
        driver.execute_script('alert("hahha")')  # 发送JS代码
        driver.switch_to.frame('iframeResult')  #切换到iframeResult
        sourse=driver.find_element_by_id('draggable')
        target=driver.find_element_by_id('droppable')
    
        #方式一:基于同一个动作链串行执行
        # actions=ActionChains(driver) #拿到动作链对象
        # actions.drag_and_drop(sourse,target) #把动作放到动作链中,准备串行执行
        # actions.perform()
    
        #方式二:不同的动作链,每次移动的位移都不同
        ActionChains(driver).click_and_hold(sourse).perform()  # 点击不动
        distance=target.location['x']-sourse.location['x'] # 获取位置差
    
        track=0
        while track < distance:
            ActionChains(driver).move_by_offset(xoffset=2,yoffset=0).perform() # 偏移位
            track+=2
    
        ActionChains(driver).release().perform()  # 释放鼠标
    
        time.sleep(10)
    
    finally:
        driver.close()
    Action Chains
    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
    from selenium.webdriver.support.wait import WebDriverWait #等待页面加载某些元素
    
    
    try:
        browser=webdriver.Chrome()
        browser.get('https://www.baidu.com')
        browser.execute_script('alert("hello world")') #打印警告
    finally:
        browser.close()
    在交互动作比较难实现的时候可以自己写JS(万能方法)
    #frame相当于一个单独的网页,在父frame里是无法直接查看到子frame的元素的,必须switch_to_frame切到该frame下,才能进一步查找
    
    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
    from selenium.webdriver.support.wait import WebDriverWait #等待页面加载某些元素
    
    
    try:
        browser=webdriver.Chrome()
        browser.get('http://www.runoob.com/try/try.php?filename=jqueryui-api-droppable')
    
        browser.switch_to.frame('iframeResult') # 切换到id为iframeResult的frame,这是整个盒子
    
        tag1=browser.find_element_by_id('droppable')  # 请放置到这里
        print(tag1)
    
        # tag2=browser.find_element_by_id('textareaCode') # 报错,在子frame里无法查看到父frame(整个盒子,iframeResult)的元素
        
        browser.switch_to.parent_frame() #切回父frame,就可以查找到了 # 切换到(整个盒子,iframeResult)
        tag2=browser.find_element_by_id('textareaCode')
        print(tag2)
    
    finally:
        browser.close()
    补充:frame的切换

    七其他

    #模拟浏览器的前进后退
    import time
    from selenium import webdriver
    
    browser=webdriver.Chrome()
    browser.get('https://www.baidu.com')
    browser.get('https://www.taobao.com')
    browser.get('http://www.sina.com.cn/')
    
    browser.back()  后退
    time.sleep(10)
    browser.forward()  前进
    browser.close()
    模拟浏览器的前进后退
    #cookies
    from selenium import webdriver
    
    browser=webdriver.Chrome()
    browser.get('https://www.zhihu.com/explore')
    print(browser.get_cookies())
    browser.add_cookie({'k1':'xxx','k2':'yyy'})
    print(browser.get_cookies())
    
    # browser.delete_all_cookies()
    
    用selenium模拟登陆后再用request模块拿到quests模块发送请求
    cookies
    # 选项卡管理:切换选项卡,有js的方式windows.open,有windows快捷键:ctrl+t等,最通用的就是js的方式
    import time
    from selenium import webdriver
    
    browser=webdriver.Chrome()
    browser.get('https://www.baidu.com')  # 第一次我打开的是百度
    browser.execute_script('window.open()')  # JS切换选项卡方式
    
    print(browser.window_handles) #获取所有的选项卡
    browser.switch_to.window(browser.window_handles[1])  # 拿到第二个选项卡
    browser.get('https://www.taobao.com') # 更改访问URL
    time.sleep(5)
    browser.switch_to.window(browser.window_handles[0])  # 拿到第一个选项卡
    browser.get('https://www.sina.com.cn') # 更改访问URL
    time.sleep(5)
    browser.close()
    选项卡管理
    from selenium import webdriver
    from selenium.common.exceptions import TimeoutException,NoSuchElementException,NoSuchFrameException
    
    try:
        browser=webdriver.Chrome()
        browser.get('http://www.runoob.com/try/try.php?filename=jqueryui-api-droppable')
        browser.switch_to.frame('iframssseResult')
    
    except TimeoutException as e:
        print(e)
    except NoSuchFrameException as e:
        print(e)
    finally:
        browser.close()
    异常处理

    八项目练习

    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
    from selenium.webdriver.support.wait import WebDriverWait #等待页面加载某些元素
    import time
    
    
    def get_goods(driver):  # 浏览器操作驱动
        try:
            goods=driver.find_elements_by_class_name('gl-item') # 所有商品块,是个列表,因为你是CLASS查找
    
            for good in goods:
                detail_url=good.find_element_by_tag_name('a').get_attribute('href') # 商品连接地址
    
                p_name=good.find_element_by_css_selector('.p-name em').text.replace('
    ','')  # 简介
                price=good.find_element_by_css_selector('.p-price i').text   # 价钱
                p_commit=good.find_element_by_css_selector('.p-commit a').text  # 多少条评论
    
                msg = '''
                商品 : %s
                链接 : %s
                价钱 :%s
                评论 :%s
                ''' % (p_name,detail_url,price,p_commit)
    
                print(msg,end='
    
    ')
    
    
            button=driver.find_element_by_partial_link_text('下一页') # 下一页键
            button.click()
            time.sleep(1)
            get_goods(driver)
        except Exception:
            pass
    
    def spider(url,keyword):  # 'https://www.jd.com/',keyword='iphone8'
        driver = webdriver.Chrome()
        driver.get(url)
        driver.implicitly_wait(3)  # 使用隐式等待
        try:
            input_tag=driver.find_element_by_id('key') # 输入框,搜索框
            input_tag.send_keys(keyword)
            input_tag.send_keys(Keys.ENTER)
            get_goods(driver) # 浏览器操作驱动
        finally:
            driver.close()
    
    
    if __name__ == '__main__':
        spider('https://www.jd.com/',keyword='iphone8')  # 主 函数调用
    
    
    
    商品 : Apple 苹果 iPhone7 Plus 手机 亮黑色 全网通 128GB
                链接 : https://item.jd.com/10673889496.html
                价钱 :6158.00
                评论 :4400+
    爬取京东商城商品信息
  • 相关阅读:
    jquery toggle(listenerOdd, listenerEven)
    struts quick start
    hdu 1518 Square (dfs)
    hdu 2544 最短路 (最短路径)
    hdu 1754 I Hate It (线段树)
    hdu 1856 More is better (并查集)
    hdu 1358 Period (KMP)
    hdu 2616 Kill the monster (DFS)
    hdu 2579 Dating with girls(2) (bfs)
    zoj 2110 Tempter of the Bone (dfs)
  • 原文地址:https://www.cnblogs.com/jokerbj/p/8258902.html
Copyright © 2011-2022 走看看