• 欢迎访问开心洋葱网站,在线教程,推荐使用最新版火狐浏览器和Chrome浏览器访问本网站,欢迎加入开心洋葱 QQ群
  • 为方便开心洋葱网用户,开心洋葱官网已经开启复制功能!
  • 欢迎访问开心洋葱网站,手机也能访问哦~欢迎加入开心洋葱多维思维学习平台 QQ群
  • 如果您觉得本站非常有看点,那么赶紧使用Ctrl+D 收藏开心洋葱吧~~~~~~~~~~~~~!
  • 由于近期流量激增,小站的ECS没能经的起亲们的访问,本站依然没有盈利,如果各位看如果觉着文字不错,还请看官给小站打个赏~~~~~~~~~~~~~!

爬虫-selenium的使用

其他 eliwang 2583次浏览 0个评论

Selenium是一个Web的自动化测试工具,最初是为网站自动化测试而开发的,可以按指定的命令自动操作,但是他需要与第三方浏览器结合在一起才能使用。如果我们把 Selenium和第三方浏览器(比如Chrome)结合在一起,就可以运行一个非常强大的网络爬虫了,这个爬虫可以处理 JavaScrip、Cookie、headers,以及任何我们真实用户需要做的事情。

一、安装

sudo pip3 install selenium

二、快速入门

from selenium import webdriver # 导入webdriver
from selenium.webdriver.common.keys import Keys #Keys`类提供键盘按键的支持,比如:RETURN, F1, ALT等
from auth_proxy import  proxyauth_plugin_path #auth_proxy模块代码在下面单独实现,用于私密代理设置

#options参数的一些常见设置
options = webdriver.ChromeOptions() #设置谷歌浏览器的一些配置选项
options.add_argument('lang=zh_CN.UTF-8') #设置编码格式
options.add_argument('--headless') #无界面浏览器
options.add_argument('--proxy-server=http://ip:port')  #设置无账号密码代理
options.add_extension(proxyauth_plugin_path) #设置私密代理
options.add_argument('user-agent=Mozilla/5.0 (iPhone; CPU iPhone OS 9_1 like Mac OS X) AppleWebKit/601.1.46 (KHTML, like Gecko) Version/9.0 Mobile/13B143 Safari/601.1') #移动版网站的反爬虫的能力比较弱,模拟iPhone6

#登录时关闭弹出的密码保存提示框,添上以下几句
prefs={"credentials_enable_service":False,"profile.password_manager_enabled":False}
options.add_experimental_option("prefs", prefs)

# 禁用浏览器弹窗
prefs = {'profile.default_content_setting_values':{'notifications' :2}}  
options.add_experimental_option('prefs',prefs)

#不加载图片, 提升速度
prefs = {'profile.managed_default_content_settings.images': 2}
options.add_experimental_option('prefs',prefs)

 #屏蔽谷歌浏览器正在接收自动化软件控制提示,加上以下两行
options.add_experimental_option('useAutomationExtension',False)
options.add_experimental_option('excludeSwitches', ['enable-automation'])

options.add_argument("disable-blink-features=AutomationControlled")#去掉webdriver痕迹
options.add_argument('--incognito') #隐身模式(无痕模式)
options.add_argument('window-size=1920x3000') #指定浏览器分辨率
options.add_argument('--no-sandbox')  #取消沙盒模式,解决DevToolsActivePort文件不存在的报错
options.add_argument('--disable-gpu')  #规避bug
options.add_argument('--disable-dev-shm-usage')  #克服有限的资源问题,用于Linux系统
options.add_argument('--hide-scrollbars') #隐藏滚动条, 应对一些特殊页面
options.add_argument('–-start-maximized') #启动就最大化
driver = webdriver.Chrome(chrome_options=options) #创建浏览器对象

driver.get("https://www.baidu.com/") # get方法会打开一个页面
driver.implicitly_wait(10) # 通常打开页面后会等待一会,让页面加载
driver.get_window_size() # 获取浏览器窗口大小
driver.set_window_size(1200,800) #设置浏览器窗口大小
driver.execute_script("window.scrollTo(0, document.body.scrollHeight);") #执行js,滚动页面到底部
print (driver.title) # 打印页面标题 "百度一下,你就知道"
driver.save_screenshot("baidu.png") # 生成当前页面快照并保存
binary_data = driver.get_screenshot_as_png() #获取当前页面快照的二进制数据

elem = driver.find_element_by_id('kw') #根据id查找元素
elem.screenshot(文件名) #对元素截图,并存储到本地
elem_data = elem.screenshot_as_png #获取当前元素截图的二进制数据
elem.size #获取当前元素大小,如{'height': 44, 'width': 108}
elem.location #获取当前元素位置,即左上角坐标,例如{'x': 844, 'y': 188}
elem.get_attribute(属性名)#获取元素的属性值
elem.text #获取当前元素的文本内容
elem.tag_name #获取当前元素标签名
elem.find_elment...#可以在当前元素内继续查找元素
elem.clear() #清空搜索框
elem.send_keys('中国') #搜索中国
elem.send_keys(Keys.RETURN) #按回车键

print(driver.page_source) # 打印网页渲染后的源代码
print(driver.get_cookies()) # 获取当前页面Cookie
print(driver.current_url) # 获取当前url
# driver.close() 关闭当前页面,如果只有一个页面,会关闭浏览器
driver.quit() # 关闭浏览器

auth_proxy.py代码实现如下:

from selenium import webdriver


def create_proxyauth_extension(proxy_host, proxy_port,
                               proxy_username, proxy_password,
                               scheme='http', plugin_path=None):
    """Proxy Auth Extension

    args:
        proxy_host (str): domain or ip address, ie proxy.domain.com
        proxy_port (int): port
        proxy_username (str): auth username
        proxy_password (str): auth password
    kwargs:
        scheme (str): proxy scheme, default http
        plugin_path (str): absolute path of the extension       

    return str -> plugin_path
    """
    import string
    import zipfile

    if plugin_path is None:
        plugin_path = 'vimm_chrome_proxyauth_plugin.zip'

    manifest_json = """
    {
        "version": "1.0.0",
        "manifest_version": 2,
        "name": "Chrome Proxy",
        "permissions": [
            "proxy",
            "tabs",
            "unlimitedStorage",
            "storage",
            "<all_urls>",
            "webRequest",
            "webRequestBlocking"
        ],
        "background": {
            "scripts": ["background.js"]
        },
        "minimum_chrome_version":"22.0.0"
    }
    """

    background_js = string.Template(
    """
    var config = {
            mode: "fixed_servers",
            rules: {
              singleProxy: {
                scheme: "${scheme}",
                host: "${host}",
                port: parseInt(${port})
              },
              bypassList: ["foobar.com"]
            }
          };

    chrome.proxy.settings.set({value: config, scope: "regular"}, function() {});

    function callbackFn(details) {
        return {
            authCredentials: {
                username: "${username}",
                password: "${password}"
            }
        };
    }

    chrome.webRequest.onAuthRequired.addListener(
                callbackFn,
                {urls: ["<all_urls>"]},
                ['blocking']
    );
    """
    ).substitute(
        host=proxy_host,
        port=proxy_port,
        username=proxy_username,
        password=proxy_password,
        scheme=scheme,
    )
    with zipfile.ZipFile(plugin_path, 'w') as zp:
        zp.writestr("manifest.json", manifest_json)
        zp.writestr("background.js", background_js)

    return plugin_path


proxyauth_plugin_path = create_proxyauth_extension(
    proxy_host="http-xxxxxxxx.com",  ##代理服务器
    proxy_port=端口号,                   ##代理端口
    proxy_username="用户名", ##认证用户名
    proxy_password="密码"  ##认证密码
)

 

三、查找元素

  • 查找单个元素(如果有多个匹配的元素,则返回第一个匹配到的元素)

    • find_element_by_id  通过id查找

      login_form = driver.find_element_by_id('loginForm')
    • find_element_by_name  通过name查找

      username = driver.find_element_by_name('username')
      password = driver.find_element_by_name('password')
    • find_element_by_xpath   通过xpath查找

      login_form = driver.find_element_by_xpath("//form[@id='loginForm']")
    • find_element_by_link_text   通过链接文本获取超链接元素

      continue_link = driver.find_element_by_link_text('Continue')
    • find_element_by_partial_link_text   通过部分链接文本获取超链接元素

      continue_link = driver.find_element_by_partial_link_text('Conti')
    • find_element_by_tag_name  通过标签名查找

      heading1 = driver.find_element_by_tag_name('h1')
    • find_element_by_class_name  通过类名查找

      content = driver.find_element_by_class_name('content')
    • find_element_by_css_selector  通过css选择器查找

      content = driver.find_element_by_css_selector('p.content'
  • 一次查找多个元素(返回的是元素列表)

    • find_elements_by_name

    • find_elements_by_xpath

    • find_elements_by_link_text

    • find_elements_by_partial_link_text

    • find_elements_by_tag_name

    • find_elements_by_class_name

    • find_elements_by_css_selector

  • 此外还有两个私有方法find_element和find_elements

    from selenium.webdriver.common.by import By
    
    driver.find_element(By.XPATH, '//button[text()="Some text"]')
    driver.find_elements(By.XPATH, '//button')

    By类的其他属性还包括:

    ID = "id"
    XPATH = "xpath"
    LINK_TEXT = "link text"
    PARTIAL_LINK_TEXT = "partial link text"
    NAME = "name"
    TAG_NAME = "tag name"
    CLASS_NAME = "class name"
    CSS_SELECTOR = "css selector"

四、鼠标动作链

有些时候,我们需要再页面上模拟一些鼠标操作,比如双击、右击、拖拽甚至按住不动等,我们可以通过导入ActionChains 类来做到。

  • 导入ActionChains类

    from selenium.webdriver import ActionChains
  • 一般样式

    ActionChains(driver).操作方法1.操作方法2.....perform()

    ActionChains对象上的操作方法存储在对象的队列中,在调用perform()方法时,才会按照队列中的顺序去触发操作

  • 常见方法

    • click(on_element=None)   

      • 单击元素。如果没有传入参数,则在当前鼠标位置进行操作
    • click_and_hold(on_element=None)

      • 在元素上单击鼠标左键并按住不放。如果没有传入参数,则在当前鼠标位置进行操作
    • context_click(on_element=None)  

      • 在元素上进行右击。如果没有传入参数,则在当前鼠标位置进行操作
    • double_click(on_element=None)

      • 在元素上进行双击。如果没有传入参数,则在当前鼠标位置进行操作
    • drag_and_drop(source,target)

      • 在起始元素上按住鼠标左键,并拖动到目标元素上进行释放
    • drag_and_drop_by_offset(source,xoffset,yoffset)

      • 鼠标点击元素,并按住偏移量进行拖放
    • move_by_offset(xoffset,yoffset)

      • 鼠标从当前位置按照偏移量进行移动
    • move_to_element(to_element)

      • 鼠标移动到元素中间位置
    • release()

      • 松掉鼠标

五、页面下拉框处理

我们已经知道了怎样向文本框中输入文字,但是有时候我们会碰到<select> </select>标签的下拉框。直接点击下拉框中的选项不一定可行。

  • WebDriver的支持类包括一个叫做 Select的类,他提供有用的方法处理这些内容:

    from selenium.webdriver.support.ui import Select
    select = Select(driver.find_element_by_name('name'))
    select.select_by_index(index) #index索引从0开始
    select.select_by_visible_text("text") #text是在option标签文本的值,是显示在下拉框的值
    select.select_by_value(value) #value是option标签的一个属性值,并不是显示在下拉框中的值
  • 取消选择

    select.deselect_all()

六、弹窗处理

Selenium WebDriver 内置了对处理弹出对话框的支持。在你的某些动作之后可能会触发弹出对话框,你可以像下面这样访问对话框:

alert = driver.switch_to.alert() # 切换进alert
print(alert.text())# 打印alert文本内容
alert.accept()# 关闭弹框(接受)
# alert.dismiss() 关闭弹窗(拒绝)
# alert.send_keys('selenium') 向弹窗里输入内容

七、页面切换

浏览器一般会打开多个窗口,切换窗口的方法如下:

driver.switch_to.window("窗口名")

或者你也可以在”switch_to.window()”中使用”窗口句柄”来打开它

script = 'window.open(https://www/zhihu.com/)'
driver.execute_script(script)#利用js在新窗口中打开知乎网
driver.switch_to.window(driver.window_handles[-1])#切换到新打开的网页

八、访问浏览器历史记录

  • 在浏览历史中前进和后退你可以使用:

    driver.forward()
    driver.back()

九、cookies

  • 获取所有cookies

    driver.get_cookies()
  • 删除某个cookie

    driver.delete_cookie("CookieName")
  • 删除所有cookies

    driver.delete_all_cookies()
  • 添加cookie

    driver.add_cookie(cookie) #cookie为dict类型

十、页面等待(Waits)

现在的大多数的Web应用程序是使用Ajax技术。当一个页面被加载到浏览器时,该页面内的元素可以在不同的时间点被加载。这使得定位元素变得困难,如果元素不再页面之中,会抛出ElementNotVisibleException异常。使用 waits, 我们可以解决这个问题。waits提供了一些操作之间的时间间隔,主要是定位元素或针对该元素的任何其他操作。

Selenium Webdriver 提供两种类型的waits:隐式和显式。显式等待会让WebDriver等待满足一定的条件以后再进一步的执行。而隐式等待让Webdriver等待一定的时间后再才是查找某元素。

  • 显示等待

    • 显式等待是你在代码中定义等待一定条件发生后再进一步执行你的代码。

    • 这里有一些方便的方法让你只等待需要的时间。WebDriverWait结合ExpectedCondition 是实现的一种方式。

      from selenium import webdriver
      from selenium.webdriver.common.by import By
      from selenium.webdriver.support.ui import WebDriverWait
      from selenium.webdriver.support import expected_conditions as EC
      
      driver = webdriver.Firefox()
      driver.get("http://somedomain/url_that_delays_loading")
      try:
          element = WebDriverWait(driver, 10).until(
              EC.presence_of_element_located((By.ID, "myDynamicElement"))
          )
      finally:
          driver.quit()

      在抛出TimeoutException异常之前将等待10秒。 WebDriverWait 默认情况下会每0.5秒调用一次ExpectedCondition直到结果成功返回。 ExpectedCondition成功的返回结果是一个布尔类型的true或是不为null的返回值。

    • 下面是一些内置的等待条件,你可以直接调用这些条件:

      title_is
      title_contains
      presence_of_element_located
      visibility_of_element_located
      visibility_of
      presence_of_all_elements_located
      text_to_be_present_in_element
      text_to_be_present_in_element_value
      frame_to_be_available_and_switch_to_it
      invisibility_of_element_located
      element_to_be_clickable – it is Displayed and Enabled.
      staleness_of
      element_to_be_selected
      element_located_to_be_selected
      element_selection_state_to_be
      element_located_selection_state_to_be
      alert_is_present
  • 隐式等待

    • 隐式等待比较简单,就是简单地设置一个等待时间,单位为秒。

    • 如果不设置,默认等待时间为0秒。

      from selenium import webdriver
      
      driver = webdriver.Firefox()
      driver.get("http://somedomain/url_that_delays_loading")
      driver.implicitly_wait(10) # seconds
      myDynamicElement = driver.find_element_by_id("myDynamicElement")

十一、执行JS

可以在加载完成的页面上使用execute_script方法执行js。 比如调用javascript API滚动页面到底部或页面的任何位置

driver.execute_script("window.scrollTo(0, document.body.scrollHeight);") #滚动到当前页面底部
driver.execute_script("document.documentElement.scrollTop=10000") #向下滚动10000像素

十二、传文件到文件上传控件

 选择 <input type=”file”> 元素并且调用 send_keys() 方法传入要上传文件的路径,可以 是对于测试脚本的相对路径,也可以是绝对路径。


开心洋葱 , 版权所有丨如未注明 , 均为原创丨未经授权请勿修改 , 转载请注明爬虫-selenium的使用
喜欢 (0)

您必须 登录 才能发表评论!

加载中……