python-selenium模块使用

Selenium模块一


一,安装

  1. 安装 selenium

    pip install selenium

  2. 安装谷歌浏览器驱动(chromedriver.exe),解压之后移动到 python 解释器的根目录

    http://chromedriver.storage.googleapis.com/index.html

    注意 :

    ​ 解压之后是一个 chromedriver.exe 程序,需要移动到 python 解释器的根目录

  3. 为什么要用 selenium ,能够加载 js 代码,把加密的部分解决了

二,简单使用

  1. 驱动浏览器
    # 创建了一个谷歌浏览器驱动的实例
    driver = webdriver.Chrome()
    
    # 打开百度官网
    driver.get('https://www.baidu.com')
    
    # 获取当前页面的源代码,审查页面的元素
    print(driver.page_source)
    
    from selenium import webdriver
    
    opt = webdriver.ChromeOptions()
    opt.binary_location = r"D:\All_Work_App\Google\Google\Chrome\Application\chrome.exe"
    chromedriver_path = 'D:\Python\CREATE_PYTHON_ENV\Spider_env\chromedriver.exe'
    driver = webdriver.Chrome(executable_path=chromedriver_path, chrome_options=opt)
    
    driver.get('https://www.baidu.com')
    
    driver.close()
    
  2. 定位元素
    1. 通过 element 定位元素

      [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-vp22w7I9-1592051716888)(assets/.png)]

      elem1 = driver.find_element_by_id()
      elem2 = driver.find_element_by_class_name()
      elem3 = driver.find_element_by_name()
      elem4 = driver.find_element_by_link_text()  # 通过文字链接定位
      
    2. 通过 xpath 定位元素

      elem = driver.find_element_by_xpath()	# 自行脑补,寻找单个
      elem = driver.find_elements_by_xpath()	# 寻找多个
      
  3. input传输框传 输内容
    elem.send_keys('hello world')
    elem.clear()	# 清空
    
  4. 模拟键盘鼠标操作

    如果浏览器加载的过慢,需要进行延时,等待浏览器加载完毕

    from selenium.webdriver.common.keys import Keys
    
    # 使用回车键进行搜索
    elem1 = driver.find_element_by_id('kw')	# 定位到 id 为 kw 的元素
    elem1.send_keys('hello')	# 给input框 传入内容
    elem1.send_keys(Keys.ENTER)	# 回车搜索
    
    # 鼠标点击按钮
    driver.find_element_by_xpath('//input[@id="su"]').click()	# 点击搜索
    driver.find_element_by_link_text('百度首页').click()	# 点击百度首页
    
  5. 关闭浏览器
    driver.close()	# 关闭当前窗口
    driver.quit()	# 关闭整个浏览器
    

三,使用 selenium 获取 cookies

from selenium import webdriver
import time

driver = webdriver.Chrome()
driver.get('https://www.baidu.com')
cooks_data = driver.get_cookies()

cookies = {}

for i in cooks_data:
    cookies[i['name']] = i['value']

print(cookies)

time.sleep(2)
driver.quit()

{'H_PS_PSSID': '26523_1427_21101_29523_29521_29098_29567_28832_29221_26350_29460', 'BIDUPSID': 'C9B38FC612177C65DDF523262D9535DB', 'delPer': '0', 'PSTM': '1565774731', 'BDORZ': 'B490B5EBF6F3CD402E515D22BCDA1598', 'BD_UPN': '12314753', 'BD_HOME': '0', 'BAIDUID': 'C9B38FC612177C65DDF523262D9535DB:FG=1'}

四,对于iframe框架窗口处理

QQ空间的窗口需要切换才能定位元素

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-9HpRYtm0-1592051716895)(assets/.png)]

定位iframe

1.id,并且唯一,直接写id
driver.switch_to_frame("x-URS-iframe")
driver.switch_to.frame("x-URS-iframe")

2.有name,并且唯一,直接写name
driver.switch_to_frame("xxxx")
driver.switch_to.frame("xxxx")

3.id,无name,先定位iframe元素
iframe = driver.find_elements_by_tag_name("iframe")[0]
driver.switch_to_frame(iframe)
driver.switch_to.frame(iframe)

================================================
import time
from selenium import webdriver
driver = webdriver.Chrome()
driver.get('https://qzone.qq.com/')

# 切换 iframe
driver.switch_to_frame('login_frame')
try:
    driver.find_element_by_id('switcher_plogin').click()
except Exception as e:
    print(e)
finally:
    time.sleep(3)
    driver.quit()
   

五,切换窗口句柄

selenium 默认在第一个窗口句柄定位元素,需要 switch 切换窗口

  1. 查看当前浏览器窗口句柄,切换句柄

    # 查看窗口句柄
    print(window_handles)
    # 切换句柄
    driver.switch_to_window(driver.window_handles[1])
    
  2. 从百度登录 qq 空间

    # 窗口处理
    import time
    
    from selenium import webdriver
    from selenium.webdriver.common.keys import Keys
    
    driver = webdriver.Chrome()
    
    driver.get('https://www.baidu.com')
    
    elem = driver.find_element_by_id('kw')
    elem.send_keys('QQ空间')
    elem.send_keys(Keys.ENTER)
    time.sleep(2)
    
    driver.find_element_by_xpath('//div[@id="content_left"]/div[1]/h3/a').click()
    
    # 查看浏览器窗口句柄并切换
    print(driver.window_handles)
    driver.switch_to_window(driver.window_handles[1])
    
    # 切换 iframe
    driver.switch_to_frame('login_frame')
    
    # 点击账号密码登录
    driver.find_element_by_id('switcher_plogin').click()
    
    # 输入账号密码
    driver.find_element_by_id('u').send_keys('xxxxxxx')
    driver.find_element_by_id('p').send_keys('xxxxxxx')
    driver.find_element_by_id('login_button').click()
    

六,弹出窗口处理

js 弹出的窗口我们不能定位,需要switch切换

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-b02YuMn0-1592051716899)(assets/.png)]

from selenium import webdriver
import time

driver = webdriver.Chrome()

driver.get('https://www.baidu.com')

driver.find_element_by_link_text('设置').click()

driver.find_element_by_link_text('搜索设置').click()
time.sleep(1)

driver.find_element_by_link_text('保存设置').click()

time.sleep(1)
alert = driver.switch_to.alert
alert.accept()

七,浏览器前进和后退

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-9XnU2LYs-1592051716906)(assets/.png)]

driver.back()
driver.forward()

八,元素的拖动

点击一个元素,把其从网页上的一个地方拖拽到另外一个地方

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-jULhi0M5-1592051716911)(assets/.png)]

import time
from selenium import webdriver
from selenium.webdriver.common.action_chains import ActionChains

driver = webdriver.Chrome()

driver.get('http://www.treejs.cn/v3/demo/cn/exedit/drag.html')

start = driver.find_element_by_id('treeDemo_2_span')
end = driver.find_element_by_id('treeDemo_14_span')


time.sleep(2)
ActionChains(driver).drag_and_drop(start, end).perform()

九,无头浏览器

性能低,无界面

import time
from selenium import webdriver

opt = webdriver.ChromeOptions()
opt.add_argument('--headless')

driver = webdriver.Chrome(chrome_options=opt)

driver.get('https://www.baidu.com')

print(driver.page_source)

Selenium模块二

一,显示等待和隐示等待

JSajax 加载之前有些按键是不能点击的,需要等待加载完毕

  1. 显示等待 : 等待某固定的条件满足

    from selenium import webdriver
    from selenium.webdriver.support.ui import WebDriverWait
    from selenium.webdriver.common.by import By
    
    # 提供判断的方法
    from selenium.webdriver.support import expected_conditions as EC
    
    wait = WebDriverWait(driver, timeout=20) # timeout是最大超时时间
    
    # presence of element located 判断元素是否加载成功
    find = wait.until(EC.presence_of_element_located((By.CLASS_NAME, 'search-keyword')))	# 也是相当于做了一次元素定位
    find.send_keys('111')	# 直接能把定位的元素拿过来用
    
    # text_to_be_present_in_element 判断文本是否出现在元素的text里面
    
    # text_to_be_present_in_element_value 判断value属性
    
    # element_to_be_clickable 判断元素是否可以点击
    
  2. 隐示等待 : 等待固定的时间,类似 time.sleep()

    driver.implicitly_wait(10)	# 在页面加载的时候都等待10秒
    

三,动作链

  1. 拖拽,移动,点击,松开

    from selenium.webdriver.common.action_chains import ActionChains
    ActionChains.drag_and_drop			参数:source, target	# 拖拽到某个元素,起始和结束
    drag_and_drop_by_offset  参数:sourcce, xoffset, yoffset # 拖拽到某个坐标点
    
    # 点击,滑动,松开
    elem = self.driver.find_element_by_class_name('gt_slider_knob')
    ActionChains(self.driver).click_and_hold(elem).perform()
    ActionChains(self.driver).move_by_offset(xoffset=x, yoffset=0).perform()
    ActionChains(self.driver).release(elem).perform()
    
  2. 截图

    # 1. 整个屏幕截图
    driver.get('https://www.bilibili.com/')
    driver.save_screenshot('snap.png')
    
    # 2. 定位元素截图
    elem = driver.find_element_by_xpath('//*[@id="lg"]/img[1]')
    elem.screenshot('1.png')
    
    # 3. 找出元素的位置,进行图片切割
    elem = driver.find_element_by_xpath('//*[@id="lg"]/img[1]')
    print(elem.location)
    {'x': 330, 'y': 149}
    print(elem.size)
    {'height': 129, 'width': 270}
    

selenium获取京东数据


  1. 请求首页
  2. 定位输入框,输入相对的内容,确定
  3. 等待元素加载完成获取源码
  4. 下一页
from selenium import webdriver
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By
import time
from lxml import etree


class JdSpider():
    binary_location = r"D:\All_Work_App\Google\Google\Chrome\Application\chrome.exe"
    chromedriver_path = 'D:\Python\CREATE_PYTHON_ENV\Spider_env\chromedriver.exe'
    def __init__(self, url):
        self.url = url
        self.wait = WebDriverWait(self.driver, timeout=10)
        self.opt = webdriver.ChromeOptions()
        self.opt.binary_location = self.binary_location
        self.driver = webdriver.Chrome(executable_path=self.chromedriver_path, chrome_options=self.opt)

    def start(self):
        self.driver.get(self.url)

    def search(self):
        # 定位输入框,输入数据
        user_input = input('请输入你要爬取的商品:\t')
        input_ = self.wait.until(EC.presence_of_element_located((By.ID, 'key')))
        input_.send_keys(user_input)
        submit = self.wait.until(EC.element_to_be_clickable((By.CLASS_NAME, 'button')))
        submit.click()

    def wait_data(self):
        # 等待商品数据加载完成
        self.wait.until(EC.presence_of_all_elements_located((By.CLASS_NAME, 'gl-item')))

    def parse_and_next(self):
        # 延时,加载30条
        self.wait_data()
        # 滑块下滑,制定js代码,如果不翻页,按钮可能没有加载出来
        js = 'window.scrollTo(0, document.body.scrollHeight)'
        self.driver.execute_script(js)
        # 延时,等待ajax加载的30条完成
        time.sleep(3)
        # 打印源代码
        html = self.driver.page_source
        self.parse_html(html)
        # 翻页
        try:
            next = self.wait.until(EC.element_to_be_clickable((By.CLASS_NAME, 'pn-next')))
            next.click()
        except TimeoutError:
            pass


    def parse_html(self, response):
        selector = etree.HTML(response)
        items = selector.xpath('//li[@class="gl-item"]')
        for item in items:
            print('title : {}'.format(item.xpath('string(.//div[contains(@class, "p-name")]/a/em)')))
            print('price : {}'.format(item.xpath('.//div[@class="p-price"]//i/text()')[0]))
            print('comment : {}'.format(item.xpath('string(.//div[@class="p-commit"])').strip()))
            print('-' * 10)
        print('一共加载{}条'.format(len(items)))


if __name__ == '__main__':
    JD = JdSpider('https://www.jd.com')
    JD.start()
    JD.search()
    while True:
        JD.parse_and_next()
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值