JavaScript
JavaScript 是网络上最常用也是支持者最多的客户端脚本语言。它可以收集 用户的跟踪数据,不需要重载页面直接提交表单,在页面嵌入多媒体文件,甚至运行网页游戏。
Ajax 当你访问一个网页时 鼠标向下滑 数据不断的更新而http网址没有变化,那么这个网页就利用了ajax异步加载技术
我们与网站服务器通信的唯一方式,就是发出 HTTP 请求获取新页面。如果提交表单之后,或从服务器获取信息之后,网站的页面不需要重新刷新,那么你访问的网站就在用Ajax 技术。
Ajax 其实并不是一门语言,而是用来完成网络任务(可以认为 它与网络数据采集差不多)的一系列技术。Ajax 全称是 Asynchronous JavaScript and XML(异步 JavaScript 和 XML),网站不需要使用单独的页面请求就可以和网络服务器进行交互 (收发信息)。
那么,如何搞定?
那些使用了 Ajax 或 DHTML 技术改变 / 加载内容的页面,可能有一些采集手段。但是用 Python 解决这个问题只有两种途径:
- 直接从 JavaScript 代码里采集内容(费时费力)
- 用 Python 的 第三方库运行 JavaScript,直接采集你在浏览器里看到的页面(这个可以有)。
微信群里有位朋友Jacky提到爬取中国银行遇到的问题,一时兴起便做了尝试。
- 首先还原问题,我们禁用js,在chrome浏览器中新建标签页,F12 > F1 >打开设置在右下角找到禁用js并勾选
- 打开中国人民银行条法司网页发现如下的页面显示
- 然后F12关闭开发者控制台,刷新页面,显示正常
- 利用chrome插件,EditThisCookie,在控制台中查看cookie如下,同时禁用js再次打开网页却发现显示正常,而清空cookie(禁用js)后打开又出现问题显示。
- 这是因为该网页首先传给你的html文件中包含cookie设置和动态跳转网址的js代码,js代码运行后会自动设置cookie并跳转链接,到达正常页面。
- 我们查看问题页面的源码,Ctrl-U
- 源码很乱,以我的菜鸡水平根本看不出来什么东西,这时需要优秀工具的帮助,http://jsbeautifier.org/ 是一款优秀js代码美化和解析工具,我们将代码放上去解析,终端curl网页得到的js代码和解析后的代码对比鲜明
- 与一般的代码美化工具比较(下图),不仅格式化了代码,并且可读化了代码,这样以我的水平就可以分析代码了。
- 首先两次请求该网址,将两次美化后的代码进行对比,我们可以看到不仅在js全局变量上有改变,在其中一个加密函数里也有小改动。
- 某一个请求里的js代码,留存参考,阅读可先跳过:
var dynamicurl = "/L3RpYW9mYXNpLzE0NDk0MS8xNDQ5NTcvaW5kZXguaHRtbA=="; var wzwschallenge = "RANDOMSTR14925"; var wzwschallengex = "STRRANDOM14925"; var template = 4; var encoderchars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";function KTKY2RBD9NHPBCIHV9ZMEQQDARSLVFDU(str) {var out, i, len;var c1, c2, c3;len = str.length;i = 0;out = "";while (i < len) {c1 = str.charCodeAt(i++) & 0xff;if (i == len) {out += encoderchars.charAt(c1 >> 2);out += encoderchars.charAt((c1 & 0x3) << 4);out += "==";break;}c2 = str.charCodeAt(i++);if (i == len) {out += encoderchars.charAt(c1 >> 2);out += encoderchars.charAt(((c1 & 0x3) << 4) | ((c2 & 0xf0) >> 4));out += encoderchars.charAt((c2 & 0xf) << 2);out += "=";break;}c3 = str.charCodeAt(i++);out += encoderchars.charAt(c1 >> 2);out += encoderchars.charAt(((c1 & 0x3) << 4) | ((c2 & 0xf0) >> 4));out += encoderchars.charAt(((c2 & 0xf) << 2) | ((c3 & 0xc0) >> 6));out += encoderchars.charAt(c3 & 0x3f);}return out; }function findDimensions() {var w = window.innerWidth || document.documentElement.clientWidth || document.body.clientWidth;var h = window.innerHeight || document.documentElement.clientHeight || document.body.clientHeight;if (w * h <= 120000) {return true;}var x = window.screenX;var y = window.screenY;if (x + w <= 0 || y + h <= 0 || x >= window.screen.width || y >= window.screen.height) {return true;}return false; }function QWERTASDFGXYSF() {var tmp = wzwschallenge + wzwschallengex;var hash = 0;var i = 0;for (i = 0; i < tmp.length; i++) {hash += tmp.charCodeAt(i);}hash *= 11;hash += 111111;return "WZWS_CONFIRM_PREFIX_LABEL4" + hash; }function HXXTTKKLLPPP5() {if (findDimensions()) {} else {var cookieString = "";cookieString = "wzwstemplate=" + KTKY2RBD9NHPBCIHV9ZMEQQDARSLVFDU(template.toString()) + "; path=/";document.cookie = cookieString;var confirm = QWERTASDFGXYSF();cookieString = "wzwschallenge=" + KTKY2RBD9NHPBCIHV9ZMEQQDARSLVFDU(confirm.toString()) + "; path=/";document.cookie = cookieString;window.location = dynamicurl;} } HXXTTKKLLPPP5();
- 这种程度的js代码(美化后)并不难理解,很明显可以看出最后的函数调用中利用document.cookie设置了两个cookie,并利用window.location设置了跳转网址,静下心去分析也能用python写出相应的加密程序,用正则取配到变量,生成我们想要的信息,但是有没有更快的方法呢。这时我们又有一个强大的工具,Js2Py,利用它我们可以解析js代码变为python中的可执行代码。如下官方简单示例:
- 下面的思路就清晰了,先利用js美化工具的python库jsbeautifier(pip安装)美化代码,然后不管js代码中关于dom操作的内容(如window.xx),取出js全局变量和加密函数,利用js2py生成可执行的python函数,以js代码中的主干逻辑在python里执行获得cookies,在requests.session中更新cookies并访问js变量中的动态网址,就可以成功到达内容页,开始爬取解析了。
- 以下为python代码,可以看到最后成功验证我们爬取到了有效信息。
import requests import re import jsbeautifier import js2pyhost_url = 'http://www.pbc.gov.cn/' dest_url = 'http://www.pbc.gov.cn/tiaofasi/144941/144957/index.html' # 利用session保存cookie信息,第一次请求会设置cookie类似{'wzwsconfirm': 'ab3039756ba3ee041f7e68f634d28882', 'wzwsvtime': '1488938461'},与js解析得到的cookie合起来才能通过验证 r = requests.session() content = r.get(dest_url).content # 获取页面脚本内容 re_script = re.search(r'<script type="text/javascript">(?P<script>.*)</script>', content.decode('utf-8'), flags=re.DOTALL) # 用点匹配所有字符,用(?P<name>...)获取:https://docs.python.org/3/howto/regex.html#regex-howto # cheatsheet:https://github.com/tartley/python-regex-cheatsheet/blob/master/cheatsheet.rst script = re_script.group('script') script = script.replace('\r\n', '') # 在美化之前,去掉\r\n之类的字符才有更好的效果 res = jsbeautifier.beautify(script) # 美化并一定程度解析js代码:https://github.com/beautify-web/js-beautify with open('x.js','w') as f:f.write(res) # 写入文档进行查看分析jscode_list = res.split('function') var_ = jscode_list[0] var_list = var_.split('\n') template_js = var_list[3] # 依顺序获取,亦可用正则 template_py = js2py.eval_js(template_js) # 将所有全局变量插入第一个函数变为局部变量并计算 function1_js = 'function' + jscode_list[1] position = function1_js.index('{') +1 function1_js = function1_js[:position]+ var_ +function1_js[position:] function1_py = js2py.eval_js(function1_js) cookie1 = function1_py(str(template_py)) # 结果类似'NA==' # 保存得到的第一个cookie cookies = {} cookies['wzwstemplate'] = cookie1 # 对第三个函数做类似操作 function3_js = 'function' + jscode_list[3] position = function3_js.index('{') +1 function3_js = function3_js[:position]+ var_ +function3_js[position:] function3_py = js2py.eval_js(function3_js) middle_var = function3_py() # 是一个str变量,结果类似'WZWS_CONFIRM_PREFIX_LABEL4132209' cookie2 = function1_py(middle_var) cookies['wzwschallenge'] = cookie2 # 关于js代码中的document.cookie参见 https://developer.mozilla.org/zh-CN/docs/Web/API/Document/cookie dynamicurl = js2py.eval_js(var_list[0])# 利用新的cookie对提供的动态网址进行访问即是我们要达到的内容页面了 r.cookies.update(cookies) content = r.get(host_url+dynamicurl).content# 最后验证是否爬取到有效信息 if u'银行卡清算机构管理办法' in content.decode('utf-8'):print('success'
作者:treelake
链接:http://www.jianshu.com/p/f5854aed87c8
來源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
Selenium
Selenium是一个Web的自动化测试工具,最初是为网站自动化测试而开发的,类型像我们玩游戏用的按键精灵,可以按指定的命令自动操作,不同是Selenium 可以直接运行在浏览器上,它支持所有主流的浏览器(包括PhantomJS这些无界面的浏览器)。
Selenium 可以根据我们的指令,让浏览器自动加载页面,获取需要的数据,甚至页面截屏,或者判断网站上某些动作是否发生。
Selenium 自己不带浏览器,不支持浏览器的功能,它需要与第三方浏览器结合在一起才能使用。但是我们有时候需要让它内嵌在代码中运行,所以我们可以用一个叫 PhantomJS 的工具代替真实的浏览器。
可以从 PyPI 网站下载 Selenium库https://pypi.python.org/simple/selenium ,也可以用 第三方管理器 pip用命令安装:
pip install selenium
Selenium 官方参考文档:http://selenium-python.readthedocs.io/index.html
PhantomJS
PhantomJS 是一个基于Webkit的“无界面”(headless)浏览器,它会把网站加载到内存并执行页面上的 JavaScript,因为不会展示图形界面,所以运行起来比完整的浏览器要高效。
如果我们把 Selenium 和 PhantomJS 结合在一起,就可以运行一个非常强大的网络爬虫了,这个爬虫可以处理 JavaScrip、Cookie、headers,以及任何我们真实用户需要做的事情。
注意:PhantomJS 只能从它的官方网站http://phantomjs.org/download.html) 下载。 因为 PhantomJS 是一个功能完善(虽然无界面)的浏览器而非一个 Python 库,所以它不需要像 Python 的其他库一样安装,但我们可以通过Selenium调用PhantomJS来直接使用。
PhantomJS 官方参考文档:http://phantomjs.org/documentation
快速入门
Selenium 库里有个叫 WebDriver 的 API。WebDriver 有点儿像可以加载网站的浏览器,但是它也可以像 BeautifulSoup 或者其他 Selector 对象一样用来查找页面元素,与页面上的元素进行交互 (发送文本、点击等),以及执行其他动作来运行网络爬虫。
# IPython2 测试代码# 导入 webdriver
from selenium import webdriver# 要想调用键盘按键操作需要引入keys包
from selenium.webdriver.common.keys import Keys# 调用环境变量指定的PhantomJS浏览器创建浏览器对象
driver = webdriver.PhantomJS()# 如果没有在环境变量指定PhantomJS位置
# driver = webdriver.PhantomJS(executable_path="./phantomjs"))# get方法会一直等到页面被完全加载,然后才会继续程序,通常测试会在这里选择 time.sleep(2)
driver.get("http://www.baidu.com/")# 获取页面名为 wrapper的id标签的文本内容
data = driver.find_element_by_id("wrapper").text# 打印数据内容
print data# 打印页面标题 "百度一下,你就知道"
print driver.title# 生成当前页面快照并保存
driver.save_screenshot("baidu.png")# id="kw"是百度搜索输入框,输入字符串"长城"
driver.find_element_by_id("kw").send_keys(u"长城")# id="su"是百度搜索按钮,click() 是模拟点击
driver.find_element_by_id("su").click()# 获取新的页面快照
driver.save_screenshot("长城.png")# 打印网页渲染后的源代码
print driver.page_source# 获取当前页面Cookie
print driver.get_cookies()# ctrl+a 全选输入框内容
driver.find_element_by_id("kw").send_keys(Keys.CONTROL,'a')# ctrl+x 剪切输入框内容
driver.find_element_by_id("kw").send_keys(Keys.CONTROL,'x')# 输入框重新输入内容
driver.find_element_by_id("kw").send_keys("itcast")# 模拟Enter回车键
driver.find_element_by_id("su").send_keys(Keys.RETURN)# 清除输入框内容
driver.find_element_by_id("kw").clear()# 生成新的页面快照
driver.save_screenshot("itcast.png")# 获取当前url
print driver.current_url# 关闭当前页面,如果只有一个页面,会关闭浏览器
# driver.close()# 关闭浏览器
driver.quit()
页面操作
Selenium 的 WebDriver提供了各种方法来寻找元素,假设下面有一个表单输入框:
<input type="text" name="user-name" id="passwd-id" />
那么:
# 获取id标签值
element = driver.find_element_by_id("passwd-id")
# 获取name标签值
element = driver.find_element_by_name("user-name")
# 获取标签名值
element = driver.find_elements_by_tag_name("input")
# 也可以通过XPath来匹配
element = driver.find_element_by_xpath("//input[@id='passwd-id']")
定位UI元素 (WebElements)
关于元素的选取,有如下的API 单个元素选取
find_element_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
-
By ID
<div id="coolestWidgetEvah">...</div>
-
实现
element = driver.find_element_by_id("coolestWidgetEvah") ------------------------ or ------------------------- from selenium.webdriver.common.by import By element = driver.find_element(by=By.ID, value="coolestWidgetEvah")
-
-
By Class Name
<div class="cheese"><span>Cheddar</span></div><div class="cheese"><span>Gouda</span></div>
-
实现
cheeses = driver.find_elements_by_class_name("cheese") ------------------------ or ------------------------- from selenium.webdriver.common.by import By cheeses = driver.find_elements(By.CLASS_NAME, "cheese")
-
-
By Tag Name
<iframe src="..."></iframe>
-
实现
frame = driver.find_element_by_tag_name("iframe") ------------------------ or ------------------------- from selenium.webdriver.common.by import By frame = driver.find_element(By.TAG_NAME, "iframe")
-
-
By Name
<input name="cheese" type="text"/>
-
实现
cheese = driver.find_element_by_name("cheese") ------------------------ or ------------------------- from selenium.webdriver.common.by import By cheese = driver.find_element(By.NAME, "cheese")
-
-
By Link Text
<a href="http://www.google.com/search?q=cheese">cheese</a>
-
实现
cheese = driver.find_element_by_link_text("cheese") ------------------------ or ------------------------- from selenium.webdriver.common.by import By cheese = driver.find_element(By.LINK_TEXT, "cheese")
-
-
By Partial Link Text
<a href="http://www.google.com/search?q=cheese">search for cheese</a>>
-
实现
cheese = driver.find_element_by_partial_link_text("cheese") ------------------------ or ------------------------- from selenium.webdriver.common.by import By cheese = driver.find_element(By.PARTIAL_LINK_TEXT, "cheese")
-
-
By CSS
<div id="food"><span class="dairy">milk</span><span class="dairy aged">cheese</span></div>
-
实现
cheese = driver.find_element_by_css_selector("#food span.dairy.aged") ------------------------ or ------------------------- from selenium.webdriver.common.by import By cheese = driver.find_element(By.CSS_SELECTOR, "#food span.dairy.aged")
-
-
By XPath
<input type="text" name="example" /> <INPUT type="text" name="other" />
-
实现
inputs = driver.find_elements_by_xpath("//input") ------------------------ or ------------------------- from selenium.webdriver.common.by import By inputs = driver.find_elements(By.XPATH, "//input")
-
鼠标动作链
有些时候,我们需要再页面上模拟一些鼠标操作,比如双击、右击、拖拽甚至按住不动等,我们可以通过导入 ActionChains 类来做到:
示例:
#导入 ActionChains 类
from selenium.webdriver import ActionChains# 鼠标移动到 ac 位置
ac = driver.find_element_by_xpath('element')
ActionChains(driver).move_to_element(ac).perform()# 在 ac 位置单击
ac = driver.find_element_by_xpath("elementA")
ActionChains(driver).move_to_element(ac).click(ac).perform()# 在 ac 位置双击
ac = driver.find_element_by_xpath("elementB")
ActionChains(driver).move_to_element(ac).double_click(ac).perform()# 在 ac 位置右击
ac = driver.find_element_by_xpath("elementC")
ActionChains(driver).move_to_element(ac).context_click(ac).perform()# 在 ac 位置左键单击hold住
ac = driver.find_element_by_xpath('elementF')
ActionChains(driver).move_to_element(ac).click_and_hold(ac).perform()# 将 ac1 拖拽到 ac2 位置
ac1 = driver.find_element_by_xpath('elementD')
ac2 = driver.find_element_by_xpath('elementE')
ActionChains(driver).drag_and_drop(ac1, ac2).perform()
填充表单
我们已经知道了怎样向文本框中输入文字,但是有时候我们会碰到<select> </select>
标签的下拉框。直接点击下拉框中的选项不一定可行。
<select id="status" class="form-control valid" onchange="" name="status"><option value=""></option><option value="0">未审核</option><option value="1">初审通过</option><option value="2">复审通过</option><option value="3">审核不通过</option>
</select>
Selenium专门提供了Select类来处理下拉框。 其实 WebDriver 中提供了一个叫 Select 的方法,可以帮助我们完成这些事情:
# 导入 Select 类
from selenium.webdriver.support.ui import Select# 找到 name 的选项卡
select = Select(driver.find_element_by_name('status'))#
select.select_by_index(1)
select.select_by_value("0")
select.select_by_visible_text(u"未审核")
以上是三种选择下拉框的方式,它可以根据索引来选择,可以根据值来选择,可以根据文字来选择。注意:
- index 索引从 0 开始
- value是option标签的一个属性值,并不是显示在下拉框中的值
- visible_text是在option标签文本的值,是显示在下拉框的值
全部取消选择怎么办呢?很简单:
select.deselect_all()
弹窗处理
当你触发了某个事件之后,页面出现了弹窗提示,处理这个提示或者获取提示信息方法如下:
alert = driver.switch_to_alert()
页面切换
一个浏览器肯定会有很多窗口,所以我们肯定要有方法来实现窗口的切换。切换窗口的方法如下:
driver.switch_to.window("this is window name")
也可以使用 window_handles 方法来获取每个窗口的操作对象。例如:
for handle in driver.window_handles:driver.switch_to_window(handle)
页面前进和后退
操作页面的前进和后退功能:
driver.forward() #前进
driver.back() # 后退
Cookies
获取页面每个Cookies值,用法如下
for cookie in driver.get_cookies():print "%s -> %s" % (cookie['name'], cookie['value'])
删除Cookies,用法如下
# By name
driver.delete_cookie("CookieName")# all
driver.delete_all_cookies()
页面等待
注意:这是非常重要的一部分!!
现在的网页越来越多采用了 Ajax 技术,这样程序便不能确定何时某个元素完全加载出来了。如果实际页面等待时间过长导致某个dom元素还没出来,但是你的代码直接使用了这个WebElement,那么就会抛出NullPointer的异常。
为了避免这种元素定位困难而且会提高产生 ElementNotVisibleException 的概率。所以 Selenium 提供了两种等待方式,一种是隐式等待,一种是显式等待。
隐式等待是等待特定的时间,显式等待是指定某一条件直到这个条件成立时继续执行。
显式等待
显式等待指定某个条件,然后设置最长等待时间。如果在这个时间还没有找到元素,那么便会抛出异常了。
from selenium import webdriver
from selenium.webdriver.common.by import By
# WebDriverWait 库,负责循环等待
from selenium.webdriver.support.ui import WebDriverWait
# expected_conditions 类,负责条件出发
from selenium.webdriver.support import expected_conditions as ECdriver = webdriver.Chrome()
driver.get("http://www.xxxxx.com/loading")
try:# 页面一直循环,直到 id="myDynamicElement" 出现element = WebDriverWait(driver, 10).until(EC.presence_of_element_located((By.ID, "myDynamicElement")))
finally:driver.quit()
如果不写参数,程序默认会 0.5s 调用一次来查看元素是否已经生成,如果本来元素就是存在的,那么会立即返回。
下面是一些内置的等待条件,你可以直接调用这些条件,而不用自己写某些等待条件了。
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 import webdriverdriver = webdriver.Chrome()
driver.implicitly_wait(10) # seconds
driver.get("http://www.xxxxx.com/loading")
myDynamicElement = driver.find_element_by_id("myDynamicElement")
当然如果不设置,默认等待时间为0。
案例一:网站模拟登录 # douban.py from selenium import webdriver from selenium.webdriver.common.keys import Keys import timedriver = webdriver.PhantomJS() driver.get("http://www.douban.com") # 输入账号密码 driver.find_element_by_name("form_email").send_keys("xxxxx@xxxx.com") driver.find_element_by_name("form_password").send_keys("xxxxxxxx") # 模拟点击登录 driver.find_element_by_xpath("//input[@class='bn-submit']").click() # 等待3秒 time.sleep(3) # 生成登陆后快照 driver.save_screenshot("douban.png") with open("douban.html", "w") as file: file.write(driver.page_source) driver.quit()案例三:执行 JavaScript 语句
-
- 隐藏百度图片
from selenium import webdriverdriver = webdriver.PhantomJS()
driver.get("https://www.baidu.com/")# 给搜索输入框标红的javascript脚本
js = "var q=document.getElementById(\"kw\");q.style.border=\"2px solid red\";"# 调用给搜索输入框标红js脚本
driver.execute_script(js)#查看页面快照
driver.save_screenshot("redbaidu.png")#js隐藏元素,将获取的图片元素隐藏
img = driver.find_element_by_xpath("//*[@id='lg']/img")
driver.execute_script('$(arguments[0]).fadeOut()',img)# 向下滚动到页面底部
driver.execute_script("$('.scroll_top').click(function(){$('html,body').animate({scrollTop: '0px'}, 800);});")#查看页面快照
driver.save_screenshot("nullbaidu.png")driver.quit()
-
- 模拟滚动条滚动到底部
#
from selenium import webdriver
import timedriver = webdriver.PhantomJS()
driver.get("https://movie.douban.com/typerank?type_name=剧情&type=11&interval_id=100:90&action=")# 向下滚动10000像素
js = "document.body.scrollTop=10000"
#js="var q=document.documentElement.scrollTop=10000"
time.sleep(3)#查看页面快照
driver.save_screenshot("douban.png")# 执行JS语句
driver.execute_script(js)
time.sleep(10)#查看页面快照
driver.save_screenshot("newdouban.png")driver.quit()
斗鱼直播案例
import unittest from selenium import webdriver from bs4 import BeautifulSoup as bsclass douyu(unittest.TestCase): # 初始化方法,必须是setUp() def setUp(self): self.driver = webdriver.PhantomJS(executable_path=r"D:\mulu\phantomjs-2.1.1-windows\phantomjs-2.1.1-windows\bin") self.num = 0 self.count = 0 # 测试方法必须有test字样开头 def testDouyu(self): self.driver.get("https://www.douyu.com/directory/all") while True: soup = bs(self.driver.page_source, "lxml") # 房间名, 返回列表 names = soup.find_all("h3", { "class" : "ellipsis"}) # 观众人数, 返回列表 numbers = soup.find_all("span", { "class" :"dy-num fr"}) # zip(names, numbers) 将name和number这两个列表合并为一个元组 : [(1, 2), (3, 4)...] for name, number in zip(names, numbers): print u"观众人数: -" + number.get_text().strip() + u"-\t房间名: " + name.get_text().strip() self.num += 1 #self.count += int(number.get_text().strip()) # 如果在页面源码里找到"下一页"为隐藏的标签,就退出循环 if self.driver.page_source.find("shark-pager-disable-next") != -1: break # 一直点击下一页 self.driver.find_element_by_class_name("shark-pager-next").click() # 测试结束执行的方法 def tearDown(self): # 退出PhantomJS()浏览器 print "当前网站直播人数" + str(self.num) print "当前网站观众人数" + str(self.count) self.driver.quit() if __name__ == "__main__": # 启动测试模块 unittest.main()