Selenium2 &headless browser&

作者: justonlyyo | 来源:发表于2018-01-24 15:53 被阅读527次

    selenium2 + 无界面浏览器 + pyquery 是个人认为功能最强大的爬虫组合(这一套本来是用做自动化测试的),有人问为啥不是bs4而是pyquery,因为我对jquery很熟悉,而且我不喜欢bs4的查询语法.所以我选择了pyquery来降低学习成本.仅此而已.这中间的无界面浏览器,最常见的是PhantomJS,但是selenium说人家phantomjs不思进取,声明将来不给它玩了(运行时会抛出"Selenium support for PhantomJS has been deprecated, please use headless versions of Chrome or Firefox instead"的警告),所以建议还是用headless版本的chrome或者firefox来替代.接下来让我们开始吧.

    安装

    安装selenium2

    pip3 install selenium
    

    或者

    pip install selenium
    

    视你的python版本和环境而定.

    如果你要安装phantomjs.

    sudo apt-get install phantomjs
    

    安装 pyquery

    pip3 install pyquery
    

    服务器端,我们建议headless版本的浏览器,比如chrome.

    安装Xvfb 一个仿真的视窗框架,可以让没有显示硬件的设备虚拟一个显示设备.

    sudo apt-get install xvfb
    

    安装PyVirtualDisplay,这是一个Xvfb的包装器.

    pip3 install pyvirtualdisplay
    

    安装chrome
    第一步,加入源列表

    sudo wget http://www.linuxidc.com/files/repo/google-chrome.list -P /etc/apt/sources.list.d/
    

    第二步 导入公钥

    wget -q -O - https://dl.google.com/linux/linux_signing_key.pub  | sudo apt-key add -
    

    第三步 更新源列表

    sudo apt-get update
    

    第四步 安装chrome

    sudo apt-get install google-chrome-stable
    

    安装完成下载chromedriver也就是headless版本的chrome.https://chromedriver.storage.googleapis.com/index.html?path=2.35/
    你也可以自行搜索chromedriver的下载地址,解压是个可执行文件,放到chrome的目录即可.
    一般ubuntu下面,chrome的目录是/opt/google/chrome/

    通过以上准备基本都齐了,我们来上一段代码:
    接下来是一个简单的操作,打开一个页面,输入密码,执行一段脚本,输入一些数据,然后提交

    #  -*- coding: utf-8 -*-
    from selenium import webdriver
    from pyvirtualdisplay import Display
    from selenium.webdriver.support.ui import WebDriverWait
    from selenium.webdriver.support import expected_conditions as ec
    from selenium.webdriver.support.select import By
    
    import datetime
    import time
    import os
    
    
    """演示"""
    
    
    display = Display(visible=0, size=(1024, 768))
    # display.start()   # 开启虚拟显示器
    
    """
    https://chromedriver.storage.googleapis.com/index.html?path=2.35/
    你也可以自行搜索chromedriver的下载地址,解压是个可执行文件,放到chrome的目录即可.
    一般ubuntu下面,chrome的目录是/opt/google/chrome/
    """
    
    chrome_driver = "/opt/google/chrome/chromedriver"  # chromedriver的路径
    os.environ["ChromeDriver"] = chrome_driver  # 必须配置,否则会在execute_script的时候报错.
    browser = webdriver.Chrome(chrome_driver)
    wait = WebDriverWait(browser, 10)
    
    
    url_1 = "https://some_url"
    browser.get(url=url_1)  # 打开页面
    
    # 密码输入按钮
    input_password = wait.until(ec.presence_of_element_located((By.CSS_SELECTOR, ".x-layout-table input[type='password']")))
    # 提交按钮
    submit_password = wait.until(ec.element_to_be_clickable((By.CSS_SELECTOR, ".x-layout-table .x-btn span")))
    
    input_password.send_keys("password")  # 输入密码
    time.sleep(1)
    submit_password.click()  # 提交密码
    
    time.sleep(3)  # 等待是为了给页面时间载入
    # 修改时间选择器输入框脚本
    js_datepicker = """let d = $(".widget-wrapper>ul>li:first input"); d.val("{}");""".\
        format(datetime.datetime.now().strftime("%F"))
    browser.execute_script(js_datepicker)  # 输入时间
    
    js_name = """let d = $(".widget-wrapper>ul>li:eq(1) input"); d.val("{}");""".format("测试人员")
    browser.execute_script(js_name)  # 输入姓名
    
    js_phone = """let d = $(".widget-wrapper>ul>li:eq(2) input"); d.val("{}");""".format("18888888888")
    browser.execute_script(js_phone)  # 输入电话
    
    js_desc_1 = """let d = $(".widget-wrapper>ul>li:eq(3) input"); d.val("{}");""".format("测试信息.")
    browser.execute_script(js_desc_1)  # 备注1
    
    
    """selenium.common.exceptions.WebDriverException: Message: unknown error: cannot focus element"""
    """ec.presence_of_all_elements_located方法可以取一组输入框,然后循环操作"""
    input_list = wait.until(ec.presence_of_all_elements_located((By.CSS_SELECTOR, ".widget-wrapper>ul>li input")))  #输入组
    submit_info = wait.until(ec.presence_of_element_located((By.CSS_SELECTOR, ".x-btn span")))  # 提交资料按钮
    submit_info.click()  # 提交信息
    
    time.sleep(1)
    browser.refresh()  # 刷新页面
    
    time.sleep(10)
    browser.quit()
    # display.stop()  # 关闭虚拟显示器
    
    

    有关pyquery的内容这里略过了,熟悉jquery的童鞋凭感觉操作就行了.0学习成本.
    补充:

    1. 有关PyVirtualDisplay的部分

    其实PyVirtualDisplay可以不装.使用headless配置项即可.我这里写了一个方法,注释里面有一些说明,和大家分享一下.

    from selenium.webdriver.support.ui import WebDriverWait
    from selenium.common.exceptions import TimeoutException
    from selenium.webdriver import FirefoxProfile
    from selenium.webdriver import FirefoxOptions
    from selenium.webdriver import Firefox
    from selenium.webdriver import ChromeOptions
    from selenium.webdriver import Chrome
    
    def get_browser(headless: bool = True, browser_class: int = 1) -> Firefox:
        """
        获取一个浏览器
        :param headless:
        :param browser_class: 浏览器种类,0是谷歌, 1 是火狐,
        :return:
        """
        """
        firefox的headless浏览器
        因为headless的浏览器的语言跟随操作系统,为了保证爬回来的数据是正确的语言,
        这里必须设置浏览器的初始化参数,
        注意,使用headless必须先安装对应浏览器正常的版本,然后再安装headless版本
        比如火狐的headless
        下载火狐的geckodriver驱动。(当前文件夹下已经有一个了)地址是:
        https://github.com/mozilla/geckodriver/releases
        下载后解压是一个geckodriver 文件。拷贝到/usr/local/bin目录下,然后加上可执行的权限
        sudo chmod +x /usr/local/bin/geckodriver
        chrome的headless浏览器
        https://chromedriver.storage.googleapis.com/index.html?path=2.35/
        你也可以自行搜索chromedriver的下载地址,解压是个可执行文件,放到chrome的目录即可.
        一般ubuntu下面,chrome的目录是/opt/google/chrome/
        据说使用root权限运行的话,chrome的headless浏览器会报异常.而firefox的headless浏览器不会!
        """
        if browser_class == 1:
            profile = FirefoxProfile()
            profile.set_preference("intl.accept_languages", "zh-cn")
            options = FirefoxOptions()
            options.add_argument("--headless")
            if headless:
                try:
                    browser = Firefox(firefox_profile=profile, firefox_options=options)
                except Exception as e:
                    title = "{} Firefox headless浏览器打开失败".format(datetime.datetime.now())
                    content = "错误原因是:{}".format(e)
                    send_mail(title=title, content=content)
                    recode(e)
                    logger.exception(e)
                    raise e
            else:
                try:
                    browser = Firefox(firefox_profile=profile)
                except Exception as e:
                    title = "{} Firefox headless浏览器打开失败".format(datetime.datetime.now())
                    content = "错误原因是:{}".format(e)
                    send_mail(title=title, content=content)
                    recode(e)
                    logger.exception(e)
                    raise e
        else:
            options = ChromeOptions()
            options.add_argument("--headless")
            if headless:
                try:
                    browser = Chrome(executable_path=chrome_driver, chrome_options=options)
                except Exception as e:
                    title = "{} Chrome headless浏览器打开失败".format(datetime.datetime.now())
                    content = "错误原因是:{}".format(e)
                    send_mail(title=title, content=content)
                    recode(e)
                    logger.exception(e)
                    raise e
            else:
                try:
                    browser = Chrome(executable_path=chrome_driver)
                except Exception as e:
                    title = "{} Chrome headless浏览器打开失败".format(datetime.datetime.now())
                    content = "错误原因是:{}".format(e)
                    send_mail(title=title, content=content)  # 这是我自定义的方法
                    recode(e)
                    logger.exception(e)
                    raise e
        return browser
    

    相关文章

      网友评论

        本文标题:Selenium2 &headless browser&

        本文链接:https://www.haomeiwen.com/subject/qgpyaxtx.html