zoukankan      html  css  js  c++  java
  • 爬虫中的selenium简单学习及案例

    selenium

    • 什么是selenium

      • 一款基于浏览器自动化的模块
    • 和爬虫的关联:

      • 模拟登录
      • 便捷的获取动态加载的数据
    • 缺点:

      • 爬取数据的效率底
      • 环境部署繁琐
    • 模块下载:

      • pip install selenium
    • selenium如何获取动态加载的数据

    • 基本编码流程

      • 导包
      • 创建一个浏览器对象,且在创建的过程中需要使用浏览器的驱动程序
      • 使用get方法进行请求发送
      • 指定其他的行为动作对应的代码
      • 关闭浏览器
    • 演示程序

      #模块引入
      from selenium import webdriver
      from time import sleep
      
      # 后面是你的浏览器驱动位置,记得前面加r'','r'是防止字符转义的
      driver = webdriver.Chrome(r'./chromedriver.exe')
      # 用get打开百度页面
      driver.get("http://www.baidu.com")
      # 查找页面的“设置”选项,并进行点击
      driver.find_elements_by_link_text('设置')[0].click()
      sleep(2)
      # 打开设置后找到“搜索设置”选项,设置为每页显示50条
      driver.find_elements_by_link_text('搜索设置')[0].click()
      sleep(2)
      
      # 选中每页显示50条
      m = driver.find_element_by_id('nr')
      sleep(2)
      m.find_element_by_xpath('//*[@id="nr"]/option[3]').click()
      m.find_element_by_xpath('.//option[3]').click()
      sleep(2)
      
      # 点击保存设置
      driver.find_elements_by_class_name("prefpanelgo")[0].click()
      sleep(2)
      
      # 处理弹出的警告页面   确定accept() 和 取消dismiss()
      driver.switch_to_alert().accept()
      sleep(2)
      # 找到百度的输入框,并输入 美女
      driver.find_element_by_id('kw').send_keys('美女')
      sleep(2)
      # 点击搜索按钮
      driver.find_element_by_id('su').click()
      sleep(2)
      # 在打开的页面中找到“Selenium - 开源中国社区”,并打开这个页面
      driver.find_elements_by_link_text('美女_百度图片')[0].click()
      sleep(3)
      
      # 关闭浏览器
      driver.quit()selenium详细用法
      
    • 基础案例

      from selenium import webdriver
      from bs4 import BeautifulSoup
      #实例化一个浏览器对象
      bro = webdriver.Chrome(executable_path='D:爬虫谷歌访问助手/chromedriver.exe')
      #发起一个get请求
      bro.get(url='http://125.35.6.84:81/xk/')
      #获取当前浏览器页面的源码数据
      page_text = bro.page_source
      #使用bs4进行解析
      soup = BeautifulSoup(page_text,'lxml')
      dl_list = soup.select('#gzlist>li>dl')
      for dl in dl_list:
          name = dl.string
          print(name)
      
    • selenium详细用法

      • 行为动作:
        • 标签定位:find系列的函数
          • find_element_by_id()
          • find_element_by_xpath()
        • 节点交互
        • 点击:click()
          • send_keys('xxx')
        • 执行js:
          • bro.execute_script('window.scrollTo(0,document.body.scrollHeight)')
        • 动作链
          • 导包:from selenium.webdriver import ActionChains
          • 创建一个动作链对象:action = ActionChains(bro)
          • 调用动作链对象中封装的属性和方法:
            • action.click_and_hold(ele)
            • move_by_offset(x,y)
            • perform():立即执行动作链
            • release()
        • page_source:返回当前浏览器显示页面的全部页面源码数据
      • 浏览器无头设置
      • 规避检测
      • 截图:save_screenshot('./1.png')
      #通过selenium实现浏览器自动化访问淘宝,并搜索关键字'华为'
      from time import sleep
      from selenium import webdriver
      #实例化一个浏览器对象
      bro = webdriver.Chrome(executable_path='D:爬虫谷歌访问助手/chromedriver.exe')
      #获取淘宝url
      bro.get('https://www.taobao.com/')
      #find系列的函数是用作于定位标签
      search_input = bro.find_element_by_id('q')
      #在淘宝首页搜索框中录入一个商品名称
      search_input.send_keys('华为')
      #阻塞两秒,防止浏览器加载阻塞导致未获取标签
      sleep(2)
      #执行JS代码
      #Js代码,让浏览器滚轮向下拖动一个屏的高度
      bro.execute_script('window.scrollTo(0,document.body.scrollHeight)')
      sleep(2)
      bro.execute_script('window.scrollTo(0,document.body.scrollHeight)')
      sleep(2)
      
      btn = bro.find_element_by_xpath('//*[@id="J_TSearchForm"]/div[1]/button')
      #绑定事件
      btn.click()
      sleep(2)
      #退出浏览器
      bro.quit()
      
      • 模拟登陆访问QQ空间

        from selenium import webdriver
        from lxml import etree
        from time import sleep
        #实例化一个浏览器对象
        bro = webdriver.Chrome(executable_path='D:爬虫谷歌访问助手/chromedriver.exe')
        #获取空间url
        bro.get('https://qzone.qq.com/')
        #switch_to操作切换frame,此时才能进行登陆页面的操作
        bro.switch_to.frame('login_frame')
        #点击使用账号密码登陆,需要绑定click事件
        bro.find_element_by_id('switcher_plogin').click()
        
        bro.find_element_by_id('u').send_keys('QQ账号')
        bro.find_element_by_id('p').send_keys('QQ密码')
        #点击登陆,绑定click事件
        bro.find_element_by_id('login_button').click()
        
        sleep(2)
        #获取登陆页面的所有的文本数据
        page_text = bro.page_source
        # 进行数据解析
        tree = etree.HTML(page_text)
        #获取内容
        data = tree.xpath('//*[@id="feed_3484622709_311_0_1560755089_0_1"]/div[1]//text()')
        print(data)
        
        sleep(3)
        bro.quit()
        
    • 相关的网站会对爬虫的请求实现监测,检测请求是否为selenium进行的发送

    • 如何让selenium规避监测?

      • 访问美团网址(规避selenium监视)示例
    from time import sleep
    from selenium.webdriver import ChromeOptions
    from selenium import webdriver
    #实例化一个ChromeOptions对象
    option = ChromeOptions()
    #设置chromedriver启动参数,规避对selenium的检测机制
    option.add_experimental_option('excludeSwitches', ['enable-automation'])
    #设定url
    url = 'https://bj.meituan.com/'
    #实例化一个浏览器对象
    bro = webdriver.Chrome(executable_path='D:爬虫谷歌访问助手/chromedriver.exe')
    # 由于美团做了一定的设置,需要进行两次get请求才可以访问
    bro.get(url)
    sleep(2)
    bro.get(url)
    #屏幕截图
    bro.save_screenshot('1.png')
    #打印当前浏览器页面的源码数据
    print(bro.page_source)
    
    • 如何设置浏览器无可视化界

      from selenium.webdriver.chrome.options import Options
      from selenium import webdriver
      from time import sleep
      # 创建一个参数对象,用来控制chrome以无界面模式打开
      chrome_options = Options()
      #设置谷歌浏览器的页面无可视化
      chrome_options.add_argument('--headless')
      chrome_options.add_argument('--disable-gpu')
      #设定url
      url = 'https://bj.meituan.com/'
      #实例化一个浏览器对象,并把设置的无可视化传入浏览器对象
      bro = webdriver.Chrome(executable_path='D:爬虫谷歌访问助手/chromedriver.exe',chrome_options=chrome_options)
      bro.get(url)
      sleep(2)
      bro.get(url)
      bro.save_screenshot('2.png')
      print(bro.page_source)
      
    • phantomJs:

      • 就是一款无可视化界面的浏览器,了解即可

      • 由于已经停止更新维护,现在已经被弃用

      • 多使用谷歌无头浏览器

    • 12306模拟登陆

      from chaojiying_Python.chaojiying import Chaojiying_Client
      from selenium import webdriver
      from selenium.webdriver import ActionChains
      from PIL import Image
      from time import sleep
      
      #调用超级鹰获取验证码
      def get_codeImg_text(imgPath, imgType):
          chaojiying = Chaojiying_Client('loukunpeng813', 'nidayedeqQ123', '	899991')	#用户中心>>软件ID 生成一个替换 96001
          im = open(imgPath, 'rb').read()													#本地图片文件路径 来替换 a.jpg 有时WIN系统须要//
          # print(chaojiying.PostPic(im, 1902))
          return chaojiying.PostPic(im, imgType)['pic_str']
      
      #实例化一个浏览器对象,并把设置的无可视化传入浏览器对象
      bro = webdriver.Chrome(executable_path='D:爬虫谷歌访问助手/chromedriver.exe')
      #获取12306的网站
      bro.get('https://kyfw.12306.cn/otn/login/init')
      sleep(2)
      #账号密码进行模拟登陆
      bro.find_element_by_id('username').send_keys('12306账号')
      bro.find_element_by_id('password').send_keys('12306密码')
      
      #想要获取验证码图片左上角和右下角亮点坐标,通过这亮点坐标可以形成一个裁剪的矩形区域
      code_img_ele = bro.find_element_by_xpath('//*[@id="loginForm"]/div/ul[2]/li[4]/div/div/div[3]/img')
      location = code_img_ele.location  # 验证码图片左上角坐标
      size = code_img_ele.size #验证码图片的长宽
      #指定矩形区域
      rangle = (int(location['x']),int(location['y']),int(location['x']+size['width']),int(location['y']+size['height']))
      #保存验证码
      bro.save_screenshot('aa.png')
      
      i = Image.open('./aa.png')
      code_img_name = 'code.png'
      frame = i.crop(rangle)
      frame.save(code_img_name)
      #进行验证码的识别
      result = get_codeImg_text(code_img_name,9004)
      print(result)
      # x1,y1|x2,y2|x3,y3                   x,y
      #[[x1,y1],[x2,y2],[x3,y3]]            [[x,y]]
      all_list = []
      if '|' in result:
          list_1 = result.split('|')
          count_1 = len(list_1)
          for i in range(count_1):
              xy_list = []
              x = int(list_1[i].split(',')[0])
              y = int(list_1[i].split(',')[1])
              xy_list.append(x)
              xy_list.append(y)
              all_list.append(xy_list)
      else:
          x = int(result.split(',')[0])
          y = int(result.split(',')[1])
          xy_list = []
          xy_list.append(x)
          xy_list.append(y)
          all_list.append(xy_list)
      
      for l in all_list:
          #x,y就是需要点击的某一个点的坐标
          x = l[0]
          y = l[1]
          #move_to_element_with_offset就是将x,y的参照系转移到指定的标签中
          #每一个动作连的操作都必须基于一个单独的动作连
          ActionChains(bro).move_to_element_with_offset(code_img_ele,x,y).click().perform()
      
      sleep(2)
      
      bro.find_element_by_id('loginSub').click()
      sleep(10)
      
      bro.quit()
      
  • 相关阅读:
    JSTL 标签库<转>
    EL表达式 <转>
    前端知识点记录
    spring boot 项目连接数据库查询数据过程
    vue -电子时钟
    XML读取
    Druid 连接池
    java JDBC自我总结
    各种数据库的链接方式总结
    Java MD5获取
  • 原文地址:https://www.cnblogs.com/Godisgirl/p/11042583.html
Copyright © 2011-2022 走看看