selecium和google

python selecium

简介

Selenium 是一个用于测试 Web 应用程序的自动化测试工具,它直接运行在浏览器中,实现了对浏览器的自动化操作,它支持所有主流的浏览器,包括 IE,Firefox,Safari,Chrome 等。

Selenium 支持所有主流平台(如,Windows、Linux、IOS、Android、Edge、Opera等),同时,它也实现了诸多自动化功能,比如软件自动化测试,检测软件与浏览器兼容性,自动录制、生成不同语言的测试脚本,以及自动化爬虫等。

本节主要研究自动化爬虫。

selecium官方文档:https://www.selenium.dev/documentation/en/

优缺点

在爬虫的时候,可能你会遇见这些问题,

页面采用多次请求,请求有前后关联,frame窗口标签,网页数据采用js代码传输,request方法获取不到js传输过来的信息代码,点击下一页的时候网页网址未发生变化,以及在爬取的时候需要挂代理,但是你又没有合适的代理池,等等问题。

这些问题selecium都能解决,因为它是调用浏览器,模拟人去点击页面,来获得数据的。使用它的时候你完全不用担心反爬措施。

缺点:效率太慢,不适合大批量采集数据。

基础知识

  • 1.下载安装

    pip install Selenium          #安装python库
    

    安装浏览器驱动

    若想使 Selenium 能够调用浏览器,那么必须通过 webdriver 驱动来实现。不同的浏览器需要使用不同驱动程序,下面列出了不同浏览器驱动程序的下载地址

    注意: 安装 Chrome、Firefox 驱动时,需要下载与浏览器版本相匹配的驱动程序,否则不能驱动浏览器,而 IE 较为特殊,您需要下载与 Selenium 版本相匹配的驱动文件

    下载之后将驱动的路径添加到环境变量中

    测试代码:

    #自动化访问百度
    # 导入seleinum webdriver接口
    from selenium import webdriver
    import time
    # 创建Chrome浏览器对象
    browser = webdriver.Chrome()
    #访问百度网站
    browser.get('http://www.baidu.com/')
    #阻塞3秒
    time.sleep(3)
    # 自动退出浏览器
    browser.quit()
    
  • 2.基本用法

    • 2.1.定位节点

      定位单个节点:

      方法 说明
      find_element_by_id() 通过 id 属性值定位
      find_element_by_name() 通过 name 属性值定位
      find_element_by_class_name() 通过 class 属性值定位
      find_element_by_tag_name() 通过 tag 标签名定位
      find_element_by_link_text() 通过标签内文本定位,即精准定位。
      find_element_by_partial_link_text() 通过标签内部分文本定位,即模糊定位
      find_element_by_xpath() 通过 xpath 表达式定位
      find_element_by_css_selector() 通过 css 选择器定位

      定位一组节点

      find_elements_by_id()
      find_elements_by_name()
      find_elements_by_class_name()
      find_elements_by_tag_name()
      find_elements_by_link_text()
      find_elements_by_partial_link_text()
      find_elements_by_xpath()
      find_elements_by_css_selector()
      

      定位一组元素的方法与定位单个元素类似,唯一的区别就是 element 后面多了一个 s(表示复数),因此上述方法的返回值是一个列表,您可以使用 for 循环拿到所有的元素节点。

    • 2.2控制浏览器

      Selenium 可以操控浏览器的窗口大小、刷新页面,以及控制浏览器的前进、后退等

      from selenium import webdriver
      driver = webdriver.Chrome()
      driver.get("http://www.baidu.com")
      #参数数字为像素点
      driver.set_window_size(480, 800)
      #设置窗口位置
      driver.set_window_position(100,200)
      #同时设置窗口的大小和坐标
      driver.set_window_rect(450,300,32,50)
      #退出浏览器
      
      from selenium import webdriver
      driver = webdriver.Chrome()
      # 访问C语言中文网首页
      first_url= 'http://c.biancheng.net'
      driver.get(first_url)
      # 访问c语言教程
      second_url='http://c.biancheng.net/c/'
      driver.get(second_url)
      # 返回(后退)到c语言中文网首页
      driver.back()
      # 前进到C语言教程页
      driver.forward()
      # 刷新当前页面相当于F5
      driver.refresh() 
      # 退出/关闭浏览器
      driver.quit()
      
    • 2.3.WebDriver常用方法

      # 请求url
      get(url)
      # 模拟键盘输入文本
      send_keys (value)
      # 清除已经输入的文本
      clear():
      # 单击已经定位的元素
      click():
      # 用于提交表单,比如百度搜索框内输入关键字之后的“回车” 操作
      submit():
      #返回属性的属性值,返回元素的属性值,可以是id、name、type 或其他任意属性
      get_attribute(name)
      # 返回布尔值,检查元素是否用户可见,比如 display属性为hidden或者none
      is_displayed() 
      

      例子:

      from selenium import webdriver
      import time
      driver = webdriver.Chrome()
      driver.get("https://www.baidu.com")
      #模拟键盘,输出文本
      driver.find_element_by_id("kw").send_keys("C语言中文网")
      #单击“百度”一下查找
      driver.find_element_by_id("su").click()
      time.sleep(3)
      #退出浏览器
      driver.quit()
      
      from selenium import webdriver
      driver = webdriver.Chrome()
      # 获取HTML结构源码
      driver.page_source
      #在源码中查找指定的字符串
      driver.page_source.find('字符串')
      # 返回百度页面底部备案信息
      text = driver.find_element_by_id("cp").text
      print(text)
      # 获取输入框的尺寸
      size = driver.find_element_by_id('kw').size
      print(size)
      
    • 2.4.selenuim时间处理

      • 鼠标事件

        Selenium WebDriver 将关于鼠标的操作方法都封装在 ActionChains 类中,使用时需要引入 ActionChains 类,如下所示:

        from selenium.webdriver.common.action_chains import ActionChains
        
        方法 说明
        ActionChains(driver) 构造 ActionChains 鼠标对象。
        click() 单击
        click_and_hold(on_element=None) 单击鼠标左键,不松开
        context_click() 右击
        double_click() 双击
        drag_and_drop() 拖动
        move_to_element(above) 执行鼠标悬停操作
        context_click() 用于模拟鼠标右键操作, 在调用时需要指定元素定位。
        perform() 将所有鼠标操作提交执行。

        例子

        from selenium import webdriver
        #导入 ActionChains 类
        from selenium.webdriver.common.action_chains import ActionChains
        driver = webdriver.Chrome()
        driver.get("http://c.biancheng.net")
        # 通过xpath表达式定位到要悬停的元素
        above = driver.find_element_by_xpath('//ul[@id="ad-link-top"]/li[1]')
        # 对定位到的元素执行鼠标悬停操作
        ActionChains(driver).move_to_element(above).perform()
        
      • 键盘事件

        Selenium WebDriver 的 Keys 模块提供了模拟键盘输入的 send_keys() 方法,除此之外,该模块也提供了操作键盘的其他方法,比如复制、粘贴等等。

        在使用之前,首先需要导入 Keys 类,如下所示:

        from selenium.webdriver.common.keys import Keys
        
        方法 说明
        send_keys(Keys.BACK_SPACE) 删除键(BackSpace)
        send_keys(Keys.SPACE) 空格键(Space)
        send_keys(Keys.TAB) 制表键(Tab)
        send_keys(Keys.ESCAPE) 回退键(Esc)
        send_keys(Keys.ENTER) 回车键(Enter)
        send_keys(Keys.CONTROL,'a') 全选(Ctrl+A)
        send_keys(Keys.CONTROL,'c') 复制(Ctrl+C)
        send_keys(Keys.CONTROL,'x') 剪切(Ctrl+X)
        send_keys(Keys.F1…Fn) 键盘 F1…Fn
        keys.down(value,element=None) 按下键盘上的某个键
        keys.up(value,element=None) 松开键盘上的某个键

        例子:

        from selenium import webdriver
        # 引入 Keys 模块
        from selenium.webdriver.common.keys import Keys
        driver = webdriver.Chrome()
        driver.get("http://www.baidu.com")
        # 输入框输入内容
        driver.find_element_by_id("kw").send_keys("C语言中文网H")
        # 删除多输入的一个H
        driver.find_element_by_id("kw").send_keys(Keys.BACK_SPACE)
        #单击“百度”一下查找
        driver.find_element_by_id("su").click()
        time.sleep(3)
        driver.quit()
        
        # 输入空格键 + “Python教程”
        driver.find_element_by_id("kw").send_keys(Keys.SPACE)
        driver.find_element_by_id("kw").send_keys("Python教程")
        # ctrl+a 全选输入框内容
        driver.find_element_by_id("kw").send_keys(Keys.CONTROL, 'a')
        # ctrl+x 剪切输入框内容
        driver.find_element_by_id("kw").send_keys(Keys.CONTROL, 'x')
        # ctrl+v 粘贴内容到输入框
        driver.find_element_by_id("kw").send_keys(Keys.CONTROL, 'v')
        # 使用回车键来代替单击操作click
        driver.find_element_by_id("su").send_keys(Keys.ENTER)
        
      • 无界面浏览器

        Chromedriver 每一次运行都要打开浏览器,并执行相应的输入、搜索等操作,这样会导致浏览器交互能力变差,浪费许多时间。 Selenium 为了增强浏览器的交互能力,允许您使用无头浏览器模式,也就是无界面浏览器,它被广泛的应用于爬虫和自动化测试中。通过以下代码可以设置无头浏览器模式:

        from selenium import webdriver
        import time
        options=webdriver.ChromeOptions()
        options.add_argument('--headless')#无界面浏览
        driver=webdriver.Chrome(options=options)
        
        driver.get('https://www.baidu.com')
        kw1=driver.find_element_by_id('kw')
        print(driver.title)
        time.sleep(3)
        #关闭当前界面,只有一个窗口
        driver.close()
        #关闭所有界面
        driver.quit()
        

        除了可以设置无头界面之外,Selenium 还支持其他一些浏览器参数设置

        opption.add_argument('--window-size=600,600') #设置窗口大小
        opption.add_argument('--incognito') #无痕模式
        opption.add_argument('--disable-infobars') #去掉chrome正受到自动测试软件的控制的提示
        opption.add_argument('user-agent="XXXX"') #添加请求头
        opption.add_argument("--proxy-server=http://200.130.123.43:3456")#代理服务器访问
        opption.add_experimental_option('excludeSwitches', ['enable-automation'])#开发者模式
        opption.add_argument('blink-settings=imagesEnabled=false')  #禁止加载图片
        opption.add_argument('lang=zh_CN.UTF-8') #设置默认编码为utf-8
        opption.add_extension(create_proxyauth_extension(
                   proxy_host='host',
                   proxy_port='port',
                   proxy_username="username",
                   proxy_password="password"
               ))# 设置有账号密码的代理
        opption.add_argument('--disable-gpu')  # 这个参数可以规避谷歌的部分bug
        opption.add_argument('--disable-javascript')  # 禁用javascript
        opption.add_argument('--hide-scrollbars')  # 隐藏滚动条
        
      • 执行js脚本

        WebDriver 提供了 execute_script() 方法来执行 JavaScript 代码,比如控制浏览器的滚动条

        from selenium import webdriver
        from time import sleep
        # 访问百度
        driver=webdriver.Chrome()
        driver.get("http://www.baidu.com")
        # 最大化浏览器窗口
        driver.maximize_window()
        # 搜索
        driver.find_element_by_id("kw").send_keys("C语言中文网")
        driver.find_element_by_id("su").click()
        sleep(3)
        # 通过js代码设置滚动条位置,数值代表(左边距,上边距)
        js="window.scrollTo(100,500);"
        #执行js代码
        driver.execute_script(js)
        sleep(5)
        driver.quit()
        

实战

  • 教程代码

    链接: http://m.biancheng.net/python_spider/selenium-case.html

    #coding:utf8
    from selenium import webdriver
    import time
    import pymongo
    class JdSpider(object):
        def __init__(self):
            self.url='http://www.jd.com/'
            self.options=webdriver.ChromeOptions() # 无头模式
            self.options.add_argument('--headless')
            self.browser=webdriver.Chrome(options=self.options) # 创建无界面参数的浏览器对象
            self.i=0  #计数,一共有多少件商品
            #输入地址+输入商品+点击按钮,切记这里元素节点是京东首页的输入栏、搜索按钮
        def get_html(self):
            self.browser.get(self.url)
            self.browser.find_element_by_xpath('//*[@id="key"]').send_keys('python书籍')
            #输入框代码,输入框输入python书籍
            
            self.browser.find_element_by_xpath("//*[@class='form']/button").click()
            #点击搜索按钮
            
            #把进度条件拉倒最底部+提取商品信息
        def get_data(self):
            # 执行js语句,拉动进度条件
            self.browser.execute_script(
                'window.scrollTo(0,document.body.scrollHeight)'
            )
            # 给页面元素加载时预留时间
            time.sleep(2)
            #用 xpath 提取每页中所有商品,最终形成一个大列表
            li_list=self.browser.find_elements_by_xpath('//*[@id="J_goodsList"]/ul/li')
            for li in li_list:
                #构建空字典
                item={}  
                item['name']=li.find_element_by_xpath('.//div[@class="p-name"]/a/em').text.strip()
                item['price']=li.find_element_by_xpath('.//div[@class="p-price"]').text.strip()
                item['count']=li.find_element_by_xpath('.//div[@class="p-commit"]/strong').text.strip()
                item['shop']=li.find_element_by_xpath('.//div[@class="p-shopnum"]').text.strip()
                print(item) 
                self.i+=1
        def run(self):
            #搜索出想要抓取商品的页面
            self.get_html()
            #循环执行点击“下一页”操作
            while True:
                #获取每一页要抓取的数据
                self.get_data()
                #判断是否是最一页
                if self.browser.page_source.find('pn-next disabled')==-1:
                    self.browser.find_element_by_class_name('pn-next').click()
                    #预留元素加载时间
                    time.sleep(1)
                else:
                    print('数量',self.i)
                    break
    if __name__ == '__main__':
        spider=JdSpider()
        spider.run()
    

    该代码是实现抓取京东商城(https://www.jd.com/)商品名称、商品价格、评论数量,以及商铺名称。比如输入搜索“Python书籍”。

  • 自己写的,selenium爬取google搜索

    前言: 运行代码之前首先要挂上外网代理,能访问到谷歌浏览器,我使用的是佛跳墙vpn,

具体代码:

  from selenium import webdriver
  import time
  from selenium.webdriver.common.keys import Keys  #输入键盘值
  import re
  
  # keyword=""
  # urls = []
  class JdSpider(object):
      #初始化代码
      def __init__(self):
          self.url='https://www.google.com'
          self.options=webdriver.ChromeOptions() # 无头模式
          self.options.add_argument('--headless')
          self.browser=webdriver.Chrome(options=self.options) # 创建无界面参数的浏览器对象
          self.keyword=""    #搜索的内容
          self.page=""    #要爬取的页数
          self.i=0  #计数,
          self.urls=[]
      def get_html(self,):
          self.browser.get(self.url)             #发起请求
          # print(self.keyword)              #输出搜索内容
          #将搜索内容填入google搜索框
          self.browser.find_element_by_xpath('//*[@name="q"]').send_keys(self.keyword)
          #点击搜索
          self.browser.find_element_by_xpath('//*[@name="q"]').send_keys(Keys.ENTER)
          #休眠3秒
          time.sleep(3)
      def get_url(self):
          #选择搜索到的域名/链接
          li_list3 =self.browser.find_elements_by_xpath('//*[@class="yuRUbf"]/a')
          for li in li_list3:
              self.i += 1
              site=re.findall('https?://(.*?)/.*?', li.get_attribute('href'))
              print(site)
              self.urls.extend(site)
      def get_echo(self):
          self.keyword = input('请输入关键字:')
          self.page=int(input('请输入要爬取的页数:'))
          # pageStart = int(input('请输入起始页'))
          # pageStop = int(input('输入结束页'))
  
      def next_page(self):
          #翻页函数
          self.page=int(self.page)
          for i in range(self.page):
              self.get_url()
              #选择到下一页,点解下一页
              self.browser.find_element_by_xpath('//*[@id="pnnext"]').click()
              time.sleep(2)
          print('数量', self.i)
  
          #输入爬取全部页面
          # while True:
          #     self.get_url()
          #     if self.browser.find_element_by_id('pnnext'):
          #         self.browser.find_element_by_id('pnnext').click()
          #         time.sleep(3)
          #     else:
          #         print('数量', self.i)
          #         break
  
      def save_url(self):
          #爬取到的域名写入文件
          self.urls=list(set(self.urls))
          with open("url.txt", 'w+') as f:
              url = "\n".join(self.urls)  # str.join:给列表里的内容之间加个换行符输出成字符串
              f.write(url)
  
      def run(self):
          self.get_echo()
          self.get_html()
          self.next_page()
          self.browser.quit()
          self.save_url()
  
  
  if __name__ == '__main__':
  
      spider=JdSpider()
      spider.run()
  

还需要解决的问题:请求超时,异常处理,

from selenium.webdriver.support.ui import WebDriverWait #设置获取元素超时时间,如果获取失败则抛出异常
from selenium.common.exceptions import TimeoutException # 超时获取元素报错原因
posted @   戴好面具  阅读(63)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?
点击右上角即可分享
微信分享提示