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
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 205,132评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,802评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,566评论 0 338
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,858评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,867评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,695评论 1 282
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,064评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,705评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 42,915评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,677评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,796评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,432评论 4 322
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,041评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,992评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,223评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,185评论 2 352
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,535评论 2 343