Selenium2 &headless browser&pyquery

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&pyquery)