Python基础(7)- Selenium使用

以前搞Java的时候,知道Selenium是做自动化测试的,后来发现搞爬虫也会用到Selenium,这里就和Python整合方面,简单学习下。

1. 什么是Selenium

Selenium是一个用于Web应用程序测试的工具。Selenium测试直接运行在浏览器中,就像真正的用户在操作一样。支持的浏览器包括IE(7, 8, 9, 10, 11),Mozilla Firefox,Safari,Google Chrome,Opera等。这个工具的主要功能包括:测试与浏览器的兼容性——测试你的应用程序看是否能够很好得工作在不同浏览器和操作系统之上。测试系统功能——创建回归测试检验软件功能和用户需求。支持自动录制动作和自动生成 .Net、Java、Perl等不同语言的测试脚本。--百度百科

官网地址:http://www.seleniumhq.org/
因为Selenium可以录制不同的动作,模拟操作,和Python结合以后,在爬取数据的时候就很方便,所以下面我们来看看需要怎样配置。

2. 安装配置

2.1火狐浏览器插件安装

插件地址:https://addons.mozilla.org/en-US/firefox/addon/selenium-ide/

安装之后,我们可以直接在浏览器中使用Selenium


2.2火狐浏览器driver下载

这个再后面会用到,地址:https://github.com/mozilla/geckodriver/releases
WebDriver是Selenium的API,我们用Python集成开发会很方便,这个下载后,需要放到Path路径下

image.png
image.png

2.3Python安装Selenium模块

pip install selenium

3.示例代码

我们先来看一个简单的例子,我们打开火狐浏览器,然后让浏览器加载一个URL

from selenium import webdriver

browser = webdriver.Firefox()
browser.get('http://www.baidu.com/')



error 信息:
  File "D:\Users\yugui\Anaconda3\lib\site-packages\selenium\webdriver\common\service.py", line 81, in start
    os.path.basename(self.path), self.start_error_message)

WebDriverException: 'geckodriver' executable needs to be in PATH. 

刚开始可能会报错,这是因为我们上面的那个driver没有加到PATH。
加到PATH后,再次执行,就可打开浏览器了


再来看一个略复杂的例子:
这是官方中的例子:http://www.seleniumhq.org/docs/03_webdriver.jsp#selenium-webdriver

from selenium import webdriver
from selenium.common.exceptions import TimeoutException
from selenium.webdriver.support.ui import WebDriverWait # available since 2.4.0
from selenium.webdriver.support import expected_conditions as EC # available since 2.26.0

#1.打开浏览器
browser = webdriver.Firefox()
#2.浏览器加载地址
browser.get('https://www.baidu.com/')
#3.输出浏览器标题
print(browser.title)
#4.一个断言,浏览器标题中包含'百度'关键字
assert '百度' in browser.title

#5.根据ID,获取搜索框
elem = browser.find_element_by_id('kw')
#模拟输入Python,进行搜索
elem.send_keys('python')
elem.submit()


try:
    # 等待浏览器刷新,返回我们的搜索结果
    WebDriverWait(browser, 10).until(EC.title_contains("python"))

    # 输出当前浏览器的标题
    print(browser.title)

finally:
    # 关闭浏览器
    browser.quit()

执行后,我们会看到,打开浏览器,然后搜索‘Python’,返回搜索结果后会关闭。

4.获取控件的方式

在上面的例子中,我们使用了find_element_by_id,就是通过标签的id来获取元素
这个和JS里面的差不多,还有很多其他的方法

#by id
#<div id="coolestWidgetEvah">...</div>
find_element_by_id(id_)

element = driver.find_element_by_id("coolestWidgetEvah")

#by class name
#<div class="cheese"><span>Cheddar</span></div><div class="cheese"><span>Gouda</span></div>
find_element_by_class_name(name)

cheeses = driver.find_elements_by_class_name("cheese")

论坛里这篇博客写的很好:Python3中Selenium使用方法

5. 实例练习

这里顺便写个小例子,练习下,我们方位豆瓣读书,然后搜索关键字,将所有的书都打印出来

import time
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
from selenium.common.exceptions import NoSuchElementException

#打开浏览器
browser = webdriver.Firefox()
#设置等待时长,最长等待10s
wait = WebDriverWait(browser,10)

#打开URL
browser.get('https://book.douban.com/')

#输出浏览器标题
print('browser title: ',browser.title)

#获取搜索框
inp_query = wait.until(EC.presence_of_element_located((By.ID,'inp-query')))
inp_query.send_keys('onepiece')
#可以直接提交,或者获取提交按钮再提交
inp_query.submit()
'''
#获取提交按钮
inp_btn =  browser.find_element_by_class_name('inp-btn').find_element_by_tag_name('input')
inp_btn.click()
'''

def show_current_page():
    print('-----------------------------------')
    print('current url: ',browser.current_url)
    
    #<ul class="subject-list">
    rs = wait.until(EC.presence_of_element_located((By.CLASS_NAME,'subject-list')))
    book_list = rs.find_elements_by_tag_name('li')
    print('current page total book: ',len(book_list))
    print('info:',browser.find_element_by_class_name('trr').text)
    
    #输出书的名字
    for book in book_list:
        print(book.find_element_by_tag_name('h2').text)
    
    print('-----------------------------------')
    
    #进入下一页
    show_next_page()

def show_next_page():
    #获取下一页的标签
    #<span class="next">
    span_next = wait.until(EC.presence_of_element_located((By.CLASS_NAME,'next')))
    try:
        #获取span中的a标签
        a_next = span_next.find_element_by_tag_name('a')
        a_next.click()
        
        show_current_page()
    except NoSuchElementException:
        #已经没有下一页,可以退出了
        print('now print all pages.')
    finally:
        browser.quit()
       
show_current_page()  
#time.sleep(10)
#退出
browser.quit()

这里的元素获取方式,不是最佳的,代码还得继续优化,这个下一页挺好玩儿的,


刚刚简单优化了下代码,主要改了些元素选择的方式,更直接了:

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
from selenium.common.exceptions import TimeoutException

#打开浏览器
browser = webdriver.Firefox()
#设置等待时长,最长等待10s
wait = WebDriverWait(browser,10)
    
def main():
    #打开URL
    browser.get('https://book.douban.com/')
    
    #输出浏览器标题
    print('browser title: ',browser.title)
    
    #获取搜索框
    inp_query = wait.until(EC.presence_of_element_located((By.ID,'inp-query')))
    inp_query.send_keys('onepiece')
    #可以直接提交,或者获取提交按钮再提交
    inp_query.submit()
    
    show_current_page()

def show_current_page():
    print('-----------------------------------')
    print('current url: ',browser.current_url)
    
    #搜索结果-汇总信息
    page_info = wait.until(EC.presence_of_element_located((By.CSS_SELECTOR,'div.article div.trr')))
    print('info: ',page_info.text)
    
    #搜索结果-书籍列表
    book_list = wait.until(EC.presence_of_all_elements_located((By.CSS_SELECTOR,'div.article ul.subject-list li.subject-item')))
    
    print('current page total book: ',len(book_list))
    for book in book_list:
        print(book.find_element_by_tag_name('h2').text)
    
    print('-----------------------------------')

    #进入下一页
    show_next_page()

def show_next_page():
    try:
        #获取下一页的标签
        a_next = wait.until(EC.presence_of_element_located((By.CSS_SELECTOR,'div.article div.paginator span.next a')))
        a_next.click()
        show_current_page()
    except TimeoutException:
        print('超时了.')
        span_next = EC.invisibility_of_element_located((By.CSS_SELECTOR,'div.article div.paginator span.next'))
        if span_next:
            print('now print all pages.')
        else :
            #真的超时,重试一次
            show_next_page()
    finally:
        browser.quit()

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

推荐阅读更多精彩内容