欢迎来到Cecilia陈的博客

孤独,是人一生最好的修行。

03 请求库之selenium

一、selenium库介绍

1.selenium最初是一个自动化测试工具,它可以自动的帮我们打开(驱动)浏览器
2.而爬虫中使用它主要是为了解决requests无法直接执行JavaScript代码的问题
1.selenium本质是通过驱动浏览器,完全模拟浏览器的操作,比如跳转、输入、点击、下拉等,来拿到网页渲染之后的结果,可支持多种浏览器
2.实际上就是通过python代码取代人为,操作浏览器

二、selenium优缺点

优点:
	1.不需要分详细分析目标网站的请求流程
    2.可以帮我们做 绕过 登录滑动认证
缺点:    
	爬虫的效率较低(相比requests来说)

三、requests库的优缺点

优点:
    1.爬虫效率高、模拟浏览器,可以只获取一个user-Agent即可,不需要等待css/js/视频等文件的加载,爬取的效率相比selenium库较高

缺点:
    每一个网站都需要,详细分析请求流程,分析时间非常耗时

四、安装selenium

pip3 install selenium

由于selenium可以帮我们驱动打开浏览器,所以我们需要安装驱动
'''
selenium支持多种浏览器,但是在使用前必须去下载与浏览器相对应的驱动。
'''
from selenium import webdriver
# 谷歌浏览器
browser=webdriver.Chrome()
# 火狐浏览器
browser=webdriver.Firefox()
# 无界面浏览器
browser=webdriver.PhantomJS()
# 苹果浏览器
browser=webdriver.Safari()
# IE浏览器
browser=webdriver.Edge() 


'''
安装selenium与谷歌驱动:
    selenium + chromedriver

下载chromed浏览器驱动:
    	把下载好的chromedriver.exe放到python安装路径的scripts目录中即可,注意最新版本是2.38,并非2.9

    	- 国内镜像网站地址:
        http://npm.taobao.org/mirrors/chromedriver/2.38/

    	- 最新的版本去官网找:
        https://sites.google.com/a/chromium.org/chromedriver/downloads

验证安装:
    - 进入python解释器:
        >>> C:\Users\Administrator>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

注意:
    selenium3默认支持的webdriver是Firfox,而Firefox需要安装geckodriver
    下载链接:https://github.com/mozilla/geckodriver/releases
'''

五、基础使用(打开浏览器)

# Author:Cecilia
from selenium import webdriver
import time


# 1.打开浏览器
'''方式一:当你下载的驱动chromedriver.exe没有放在python安装包的script下时
        需要将你下载的驱动的本地路劲,给executable_path参数
'''
# driver = webdriver.Chrome(executable_path=r'C:\Users\Administrator\Desktop\chromedriver.exe')
'''方式二:如果你的驱动是放在python安装包中script文件夹中(推荐使用),不用带任何参数'''
driver = webdriver.Chrome()


# 2.往目标网站发送请求
driver.get('https://www.baidu.com')


# 3.获取数据
input_tag = driver.find_element_by_id('kw')# 获取id为kw的input标签
print(input_tag) #返回的是一个对象
#往百度首页输入框中发送参数(对象有一个方法send_keys---发送参数的)
input_tag.send_keys('小狗')
time.sleep(1)

# 找到百度一下的按钮
submit_button = driver.find_element_by_id('su')
submit_button.click() #执行按钮单击事件

六、等待元素被加载

1、selenium只是模拟浏览器的行为,而浏览器解析页面是需要时间的(执行css,js),一些元素可能需要过一段时间才能加载出来,为了保证能查找到元素,必须等待

2、等待的方式分两种:
隐式等待:在browser.get('xxx')前就设置,针对所有元素有效
显式等待:在browser.get('xxx')之后设置,只针对某个元素有效

1. 隐式等待

# Author:Cecilia

from selenium import webdriver
import time

# 简单使用
# webdriver.Chrome('谷歌浏览器的驱动路径')  # 指向谷歌浏览器驱动
# webdriver.Firefox('火狐浏览器的驱动路径')  # 指向火狐浏览器驱动

# 使用步骤 (*******)
# 1.通过谷歌浏览器驱动,打开谷歌浏览器
driver = webdriver.Chrome()
try:
    # 2.往目标网站发送请求
    driver.get('https://www.baidu.com/')


    # 隐式等待,等待所有标签元素加载
    driver.implicitly_wait(10)

    # 3.获取数据
    # 根据id查找百度的input输入框
    input_tag = driver.find_element_by_id('kw')

    # 往百度输入输入小狗
    input_tag.send_keys('小狗')

    # 点击百度一下的按钮
    submit_button = driver.find_element_by_id('su')
    submit_button.click()

    time.sleep(5)

    # 当你正在请求的时候,突然断网了,可以捕获一下异常,让你的程序不报错。
    # 打印一下错误信息
    # 将驱动关闭
except Exception as e:
    print(e)

finally:
    driver.close()

2. 显示等待

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()

七、选择器

# 所有用法---基础用法
- find_element: 找第一个
- find_elements: 找所有

find_element_by_id()    #id
find_element_by_class_name()  #class 
find_element_by_css_selector()   #id   .class
find_element_by_link_text()  #文本
find_element_by_name()   #name属性
find_element_by_partial_link_text()  #局部文本
find_element_by_tag_name()  # 了解

driver.find_element_by_xpath()   xpath解析语法

模拟百度登录操作为例

# Author:Cecilia

from selenium import webdriver
import time
driver = webdriver.Chrome()

try:

    # 1.发送请求
    driver.get('https://www.baidu.com/')

    # 2.隐式等待
    driver.implicitly_wait(10)

    # 3.开始查找标签元素
    '''
    *********
    - find_element: 找第一个
    - find_elements: 找所有

    driver.find_element_by_id()    id
    driver.find_element_by_class_name()  class 
    driver.find_element_by_css_selector()   #id   .class
    driver.find_element_by_link_text()  文本
    driver.find_element_by_name()   name属性
    driver.find_element_by_partial_link_text()  局部文本
    driver.find_element_by_tag_name()  # 了解

    driver.find_element_by_xpath()   xpath解析语法
    '''
    # time.sleep(1)

    # driver.find_element_by_name()   name属性
    # tj_login = driver.find_element_by_name('tj_login')

    # 模拟百度登录操作
    # 1.根据登录文本查找登录a标签,并点击登录按钮
    tj_login = driver.find_elements_by_link_text('登录')#全部文本
    # tj_login = driver.find_elements_by_partial_link_text('登')#局部文本
    # 2.点击事件
    tj_login.click()

    # 2.查找用户名与密码登录按钮并点击
    # # 根据id查找该按钮
    user_and_pwd_button = driver.find_element_by_id('TANGRAM__PSP_10__footerULoginBtn')
    user_and_pwd_button.click()


    #3.根据name属性选择器查找用户名输入框  (name属性必须唯一)
    user_input = driver.find_element_by_name('userName')
    user_input.send_keys('cc') # 向文本框中输入值

    # 4.根据class属性查找密码输入框 (class必须唯一)
    pwd_input = driver.find_element_by_class_name('pass-text-input-password')
    pwd_input.send_keys('123456')
    # 5.根据id查找确定登录按钮,并点击
    submit_login = driver.find_element_by_id('TANGRAM__PSP_10__submit')
    submit_login.click()

finally:
    driver.close()

八、获取标签属性

# Author:Cecilia

from selenium import webdriver
import time

driver = webdriver.Chrome()  # 驱动打开浏览器
try:
    # 1.打开百度url
    driver.get('https://www.baidu.com')
    # 2.隐式等待
    driver.implicitly_wait(10)

    # 3.通过name属性找到百度的搜索框
    search_input = driver.find_element_by_name('wd')

    '''获取标签属性'''
    print(search_input.id) # 获取标签的id
    print(search_input.tag_name)# 获取标签的名称
    print(search_input.location)# 获取标签的位置
    print(search_input.size)# 获取标签的大小

except Exception as e:
    print(e)

finally:
    driver.close()

九、百度搜索框多次搜索

# Author:Cecilia

# Author:Cecilia

from selenium import webdriver
import time

driver = webdriver.Chrome()  # 驱动打开浏览器
try:
    # 1.打开百度url
    driver.get('https://www.baidu.com')
    # 2.隐式等待
    driver.implicitly_wait(10)

    # 3.通过name属性找到百度的搜索框
    search_input = driver.find_element_by_name('wd')
    search_input.send_keys('小狗')


    # 4.通过css选择器找到百度一下按钮
    submit_button = driver.find_element_by_id('su')
    submit_button.click()  #执行按钮单击事件# 百度点击搜索小狗

    # 5.延时3秒进行下一次搜索
    time.sleep(3)
    # 6.将搜索框中的内容清除
    search_input.clear()
    # 7.进行搜索小猫
    search_input.send_keys('小猫')
    # 延时一下,更像人为的操作
    time.sleep(2)
    # 8.获取页面中的搜索确定按钮
    submit_button.click()

except Exception as e:
    print(e)

十、其他操作

1. 模拟浏览器前进后退

# Author:Cecilia
import time
from selenium import webdriver


browser=webdriver.Chrome()
browser.get('https://www.baidu.com') # 先访问百度
time.sleep(2) # 在百度首页停留2秒
browser.get('https://www.taobao.com')# 在访问淘宝页面
time.sleep(3)# 在淘宝首页停留3秒
browser.back() #回到百度首页

time.sleep(5)# 在百度首页再次停留5秒
browser.get('http://www.sina.com.cn/') # 到新浪首页
time.sleep(3)
browser.back()# 在回到百度首页
time.sleep(5) # 在停留5秒后
browser.forward()# 前进到新浪首页
time.sleep(3)
browser.close()# 关闭浏览器

2. cookies

# Author:Cecilia

import time
from selenium import webdriver

browser=webdriver.Chrome()
browser.get('https://www.zhihu.com/explore') # 访问知乎
print(browser.get_cookies())# 打印cookies

3. 选项卡管理(以新的标签页打开)

# Author:Cecilia

import time
from selenium import webdriver

browser=webdriver.Chrome()
browser.get('https://www.baidu.com') # 访问百度url
browser.execute_script('window.open()')

print(browser.window_handles) #获取所有的选项卡
browser.switch_to_window(browser.window_handles[0])
browser.get('https://www.taobao.com')

time.sleep(2)
browser.execute_script('window.open()')
browser.switch_to_window(browser.window_handles[0])
browser.get('https://www.sina.com.cn')
browser.close()

4. iframe标签

# Author:Cecilia

from selenium import webdriver

try:
    browser=webdriver.Chrome()
    browser.get('http://www.runoob.com/try/try.php?filename=jqueryui-api-droppable')
    browser.switch_to.frame('iframssseResult')
    '''
    iframe标签是即将要淘汰的标签
    它是在一个html文件中,有一个iframe标签,iframe标签中又有一个html页面,
    在整体的HTML页面中是访问不到这个iframe标签里嵌套的html页面的,只能通过switch_to方法切换过去,
    两个html页面是没有关系的
    '''
except Exception as e:
    print(e)

十一、联系小项目

1. 模拟人为输入商品爬取feelunique商品基本信息

# Author:Cecilia

from selenium import webdriver
import time

def good_data(driver,f):
    good_all_list = driver.find_elements_by_class_name('m-product-wrapper') # 获取所有的商品
    f.write('-----------------------------------------------------------------------------------------------------------------------------------')
    for good in good_all_list:# 循环商品列表
        '''1.获取商品图片'''
        good_img_tag = good.find_element_by_css_selector('.m-product-wrapper a img')#获取商品img标签
        good_img = good_img_tag.get_attribute('data-src')# 获取商品data_src属性值,就是图片的数据
        print(good_img)
        '''2.获取商品英镑价格'''
        good_english_price = 'f%s'%good.find_element_by_css_selector('.p-price>span>span').text
        print(good_english_price)
        '''3.获取商品人民币价格'''
        good_china_price = good.find_element_by_css_selector('.p-reference span').text
        print(good_china_price)
        '''4.获取商品简介'''
        good_title = good.find_element_by_css_selector('.m-product-name').text
        print(good_title)
        '''5.获取商品的生产地址'''
        good_bri = good.find_element_by_css_selector('.m-product-warehouse').text
        print(good_bri)
        f.write(
            f'''
            商品名称: {good_title}
            商品图片: {good_img}
            商品英镑价格: {good_english_price}
            商品中国价格: {good_china_price}
            商品生产地址: {good_bri}
            '''
        )


    '''获取下一页按钮'''
    next_button = driver.find_element_by_css_selector('.page-item>.next')
    next_button.click()
    time.sleep(2)
    good_data(driver,f) # 进行递归循环,获取每一页的数据


if __name__ == '__main__':
    f = open('kouhong.txt', 'a', encoding='utf-8')
    driver = webdriver.Chrome() #驱动打开浏览器
    try:
        driver.get('https://cn.feelunique.com/') #访问淘宝首页
        search_input = driver.find_element_by_id('q')# 通过id属性获取搜索框标签
        search_input.send_keys('口红') #向搜索框中输入搜索词

        search_button = driver.find_element_by_class_name('btn-search')# 通过class属性获取搜索按钮
        search_button.click()

        # 调用获取数据的方法
        good_data(driver,f)
        time.sleep(20)

    except Exception as e:
        print(e)
    finally:
        driver.close()

2. 爬取京东商品

from selenium import webdriver
from selenium.webdriver.common.keys import Keys  # 可以帮我们操作键盘
import time

def get_data(driver, f):
    time.sleep(1)
    js_code = '''
            window.scrollTo(0, 5500)
        '''
    # execute_script: 该方法可以执行js代码
    driver.execute_script(js_code)

    # 执行完js代码后,等待2秒加载数据
    time.sleep(2)

    # 操控滚动条,向下滑动
    # find_elements ---> [element_obj]
    goods_list = driver.find_elements_by_class_name('gl-item')
    for goods in goods_list:
        # print(goods)

        # 商品名称
        goods_name = goods.find_element_by_css_selector('.p-name em').text
        print(goods_name)

        # 商品详情页url
        # img_tag = goods.find_element_by_class_name('p-img')
        # a_tag = img_tag.find_element_by_tag_name('a')
        # # 获取a标签中的属性
        # href = a_tag.get_attribute('href')
        # print(href)
        a_tag = goods.find_element_by_css_selector('.p-img a')
        # get_attribute:获取标签元素的属性
        goods_url = a_tag.get_attribute('href')
        print(goods_url)

        # 获取商品图片
        img_tag = goods.find_element_by_css_selector('.p-img a img')
        goods_img = img_tag.get_attribute('src')
        print(goods_img)

        # 商品价格
        goods_price = goods.find_element_by_css_selector('.p-price i').text
        print(goods_price)

        # 商品评价人数
        goods_commit = goods.find_element_by_css_selector('.p-commit a').text
        print(goods_commit)

        f.write(
            f'''
            商品名称: {goods_name}
            商品详情: {goods_url}
            商品图片: {goods_img}
            商品价格: {goods_price}
            评价人数: {goods_commit}
            ----------------------------------------------
            '''
        )

    # 注意: 爬取完当前页后,点击下一页
    next_tag = driver.find_element_by_class_name('pn-next')
    next_tag.click()
    time.sleep(2)

    # 递归执行爬取当前商品所有数据
    get_data(driver, f)


if __name__ == '__main__':

    f = open('jd.txt', 'a', encoding='utf-8')

    driver = webdriver.Chrome()

    # 爬取京东商品信息
    try:
        # 1.发送请求
        driver.get('https://www.jd.com/')

        # 2.隐式等待
        driver.implicitly_wait(10)

        # 3.根据id找到商品输入框
        input_tag = driver.find_element_by_id('key')
        input_tag.send_keys('坦克')
        input_tag.send_keys(
            Keys.ENTER  # 调用电脑回车键
        )

        # 4.调用爬取商品信息函数
        get_data(driver, f)

        time.sleep(1000)

    finally:
        driver.close()
posted @ 2020-01-05 19:05  Cecilia陈  阅读(257)  评论(0编辑  收藏  举报