使用selenium+PhantomJS实现简单登录

Selenium本是一个用于Web应用程序测试的工具。Selenium测试直接运行在浏览器中,就像真正的用户在操作一样。PhantomJS是一个基于WebKit的服务器端 JavaScript API。它全面支持web而不需浏览器支持。使用selenium和PhantomJS这两个工具来爬虫,可以实现很多功能。

Selenium和PhantomJS

selenium是一个强大的网络数据采集工具,最初是为了网站自动化测试而开发的。它可以让浏览器自动加载页面,获取需要的数据,也可以截屏,或判断网站上某些动作是否发生。

PhantomJS是一个无头浏览器,它不会向用户展示网页的图形界面。

简单理解selenium就是完成模拟用户所有操作的工具,而PhantomJS则是一个没有图形界面,可供selenium实现各种操作的浏览器。

代码部分

#!/usr/bin/env python
# @Time    : 2017/2/25
# @Author  : AlPha
# @File    : selenium模拟登陆教务网站.py
# @Version : 3.5
# @Software: PyCharm Community Edition
# @Blog    : http://alpha87.github.io

from selenium import webdriver

browser = webdriver.PhantomJS(executable_path="C:\phantomjs.exe")
browser.implicitly_wait(30)
browser.get("http://210.31.122.109")

browser.find_element_by_name("txtUserName").clear()
browser.find_element_by_name("txtUserName").send_keys("201303010121")
browser.find_element_by_name("TextBox2").clear()
browser.find_element_by_name("TextBox2").send_keys("password")

browser.save_screenshot(str("登录界面.jpg"))
browser.find_element_by_name("txtSecretCode").send_keys(input("输入验证码\n>>> "))
browser.find_element_by_class_name("btn_dl").click()
print(browser.page_source)
browser.close()

分析代码

from selenium import webdriver

用来导入selenium库。

browser = webdriver.PhantomJS(executable_path="C:\phantomjs.exe")

用来指明PhantomJS可执行文件的路径。

browser.implicitly_wait(30)

是隐式等待30秒。一旦设定,browser对象实例的整个生命周期的隐式调用也就设定好了。

browser.get("http://210.31.122.189")

打开指定网址。

browser.find_element_by_name("txtUserName").clear()
browser.find_element_by_name("txtUserName").send_keys("201303010121")
browser.find_element_by_name("TextBox2").clear()
browser.find_element_by_name("TextBox2").send_keys("password")

这四行代码分别对应的是:

1.清除用户名中原来的信息。

2.键入学号。

3.清除密码中原来的信息。

4.键入密码。

browser.save_screenshot(str("登录界面.jpg"))
browser.find_element_by_name("txtSecretCode").send_keys(input("输入验证码\n>>> "))
browser.find_element_by_class_name("btn_dl").click()
print(browser.page_source)

这四行代码分别实现的功能是:

1.把登录页面截图,保存到当前文件夹下。(保存登录页面的截图是为了可以查看当前网页的验证码)

2.键入验证码。

3.点击登录。

4.打印登录以后页面的源码。

browser.close()

用来关闭操作。

用户登录界面源码

selenium用法拓展

元素定位

Selenium提供了下面的方法进行元素定位:

find_element_by_id
find_element_by_name
find_element_by_xpath
find_element_by_link_text
find_element_by_partial_link_text
find_element_by_tag_name
find_element_by_class_name
find_element_by_css_selector

寻找多个元素(下列方法会返回一个列表):

find_elements_by_id
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

例如:

<html>
 <body>
  <form id="loginForm">
   <input name="username" type="text" />
   <input name="password" type="password" />
   <input name="continue" type="submit" value="Login" />
  </form>
 </body>
<html>

可以这样定位表单元素form:

login_form = driver.find_element_by_id('loginForm')

异步加载

现在很多Web应用都在使用AJAX技术。浏览器载入一个页面时,页面内的元素可能是在不同的时间载入的, 这会加大定位元素的困难程度,因为元素不在DOM里,会抛出 ElementNotVisibleException 异常, 使用 waits,我们就可以解决这个问题。

显式等待

显式的 waits 等待一个确定的条件触发然后才进行更深一步的执行。 最糟糕的的做法是 time.sleep(),这指定的条件是等待一个指定的时间段。 这里提供一些便利的方法让你编写的代码只等待需要的时间,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_delay_loading")
try:
    element = WebDriverWait(driver,10).until(
        EC.presence_of_element_located((By.ID,"myDynamicElement"))
    )
finally:
    driver.quit()

这段代码会等待10秒,如果10秒内找到元素则立即返回,否则会抛出 TimeoutException 异常, WebDriverWait默认每500毫秒调用一下 ExpectedCondition直到它返回成功为止。ExpectedCondition 类型是布尔的,成功的返回值就是true,其他类型的 ExpectedCondition 成功的返回值就是 not null。

Expected Conditions

自动化网页操作时,有许多频繁使用到的通用条件。下面列出的是每一个条件的实现。 Selenium + Python 提供了许多方便的方法,因此你不需要自己编写 expected_condition 的类, 或者创建你自己的通用包。

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

from selenium.webdriver.support import expected_conditions as EC
wait = WebDriverWait(driver,10)
element = wait.until(EC.element_to_be_clickable((By.ID,'someid')))

expected_conditions 模块包含了一系列预定义的条件来和WebDriverWait使用。

隐式等待

当我们要找一个或者一些不能立即可用的元素的时候,隐式 waits 会告诉WebDriver轮询DOM指定的次数,默认设置是0次。 一旦设定,WebDriver对象实例的整个生命周期的隐式调用也就设定好了。

from selenium import webdriver

driver = webdriver.Firefox()
driver.implicitly_wait(10) 
driver.get("http://somedomain/url_that_delays_loading")
myDynamicElement = driver.find_element_by_id('myDynamicElement')

其他用法

这部分是我看其他教程总结的一些零碎用法。

1.浏览器最大化:

browser.maximize_window()

2.查看页面:

browser.page_sources

3.设置浏览器宽和高:

browser.set_window_size(480,800)

4.操作对象常用方法:

click() #点击对象
send_keys() #在对象上模拟输入
text #获取元素的文本信息
submit #用于提交表单,某些情况下和click()用法相同

5.截图:

browser.save_screenshot

6.用链接文本定位超链接:

#源码部分
<a href="continue.html">Continue</a>
#定位
continue_link = browser.find_element_by_link_text('Continue')

7.使用cookies:

cookies = {
  "name":"foo"
  "value":"bar"
}
browser.add_cookie(cookies)
# And now output all the available cookies for the current URL
driver.get_cookies()

8.前进和后退页面:

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

推荐阅读更多精彩内容