最新消息:备用域名:https://yeeach.me

Python中使用selenium作为Web Browser引擎

技术 admin 4541浏览 12评论

由于目前的Web开发中AJAX、Javascript、CSS的大量使用,一些网站上的重要数据是由Ajax或Javascript动态生成的,并不能直接通过解析html页面内容就能获得(例如采用mechanizelxmlBeautiful Soup )。要实现对这些页面数据的爬取,爬虫必须支持Javacript、DOM、HTML解析等一些浏览器html、javascript引擎的基本功能。

正如Web Browser Programming in Python总结的,在python程序中,有如下一些项目提供能类似功能:

其中Pyv8主要是Google Chrome V8 Javascript引擎的Python封装,侧重在Javacript操作上,并不是完整的Web Browser 引擎,而诸如PythonWebKitPython-SpidermonkeyPyWebKitGtk等几个主要在Linux平台上比较方便,而HulaHopPamie处理MS IE 。因此从跨平台、跨浏览器、易用性等角度考虑,以上方案并不是最好的。

SeleniumWindmill 原本主要用于Web自动化测试上,对跨操作系统、跨浏览器有较好的支持。其对Javacript、DOM等操作的支持主要依赖操作系统本地的浏览器引擎来实现,因此爬虫所必须的大部分功能,SeleniumWindmill 都有较好的支持。在性能要求不高的情况下,可以考虑采用SeleniumWindmill的方案,从评价来看,WindmillSelenium功能更加全面。

争取其他语言一些类似的软件还有:

  • Lobo Browser(Java Browser)
  • Rhino (Java Javascript Engine)
  • HtmlunitTestNG (Java  Testing Framework)
  • Watir (Ruby)
  • 1、应用场景

    关于Selenium的详细说明,可以参考其文档, 这里使用Python+Selenium Remote Control (RC)+Firefox 来实现如下几个典型的功能:

    1)、Screen Scraping,也即由程序自动将访问网页在浏览器内显示的图像保存为图片,类似那些digg站点的网页缩略图。Screen Scraping有分成两种:只Scraping当前浏览器页面可视区域网页的图片(例如google.com首页),Scraping当前浏览器完整页面的图片(页面有滚动,例如www.sina.com.cn的首页有多屏,需要完整保存下来)

    2)、获取Javascript脚本生成的内容

    例如要用程序自动爬取并下载百度新歌TOP100 的所有新歌,以下载萧亚轩的《抱紧你》为例,大致步骤可以如下:

    a)、进入百度新歌TOP100http://list.mp3.baidu.com/top/top100.html,通过正则表达式匹配<a target=”_blank” href=”http://mp3.baidu.com/m?(.*)” class=”search”></a> 或采用mechanizeBeautiful Soup之类的htmlparser解析页面获得每一首歌后面的查询地址

    b)、在查询结果页面,获得第一条结果的地址<a href=”http://202.108.23.172(.*)” title=”(.*)</a>,进入mp3的实际下载地址

    c)、在歌曲实际下载页面,解析html页面内容,会发现mp3的实际现在地址为空

       <a id="urla" href="" onmousedown="sd(event,0)" target="_blank"></a>

    实际的下载地址是由javascript脚本设置的:

                        var encurl = "…", newurl = "";
                        var urln_obj = G("urln"), urla_obj = G("urla");
                        newurl = decode(encurl);
                        urln_obj.href = urla_obj.href = song_1287289709 = newurl;
      其中函数G(str)为:
        	function G(str){
    			return document.getElementById(str);
    		};

    因此直接解析页面并不能获得下载地址,必须通过python调用浏览器引擎来解析javascript代码后获得对应的下载地址。

    2、Selenium RC基础

    Selenium RC的运行机制及架构在官方文档中有详细说明

    Selenium RC主要包括两部分:Selenium Server、Client Libraries,其中:

    • The Selenium Server which launches and kills browsers, interprets and runs the Selenese commands passed from the test program, and acts as an HTTP proxy, intercepting and verifying HTTP messages passed between the browser and the AUT.

    Selenium Server 对应Selenium RC 开发包中的selenium-server-xx目录,其中

    xx对应相应的版本

    • Client libraries which provide the interface between each programming language and the Selenium-RC Server.

    Selenium RC提供了包括java、python、ruby、perl、.net、php等语言的client driver,分别如下:

    selenium-dotnet-client-driver-xx

    selenium-java-client-driver-xx

    selenium-perl-client-driver-xx

    selenium-php-client-driver-xx

    selenium-python-client-driver-xx

    selenium-ruby-client-driver-xx

    Selenium,Python,Screen Scraping,Web Scraping,爬虫

    Python等语言通过调用client driver来发出浏览器操作指令(例如打开制定url),由client driver把指令传递给Selenium Server解析。Selenium Server负责接收、解析、执行客户端执行的Selenium 指令,转换成各种浏览器的命令,然后调用相应的浏览器API来完成实际的浏览器操作。

    Selenium Server实际充当了客户端程序与浏览器间http proxy。

    3、例子:

    1)、下载Selenium RC http://seleniumhq.org/download/,测试使用的selenium-remote-control-1.0.3.zip

    2)、解压后selenium-remote-control-1.0.3.zip

    3)、运行Selenium Server

    cd  selenium-remote-control-1.0.3\selenium-server-1.0.3

    java -jar  selenium-server.jar

    Selenium Server缺省监听端口为4444,在org.openqa.selenium.server.RemoteControlConfiguration中设定

    4)、测试代码

    #coding=gbk
    from selenium import selenium
    
    def selenium_init(browser,url,para):
        sel = selenium('localhost', 4444, browser, url)
        sel.start()
        sel.open(para)
        sel.set_timeout(60000)
        sel.window_focus()
        sel.window_maximize()
        return sel
    
    def selenium_capture_screenshot(sel):
        sel.capture_screenshot("d:\\singlescreen.png")
    
    def selenium_get_value(sel):
        innertext=sel.get_eval("this.browserbot.getCurrentWindow().document.getElementById('urla').innerHTML")
        url=sel.get_eval("this.browserbot.getCurrentWindow().document.getElementById('urla').href")
        print("The innerHTML is :"+innertext+"\n")
        print("The url is :"+url+"\n")
    
    def selenium_capture_entire_page_screenshot(sel):
        sel.capture_entire_page_screenshot("d:\\entirepage.png", "background=#CCFFDD")
    
    if __name__ =="__main__" :
        sel1=selenium_init('*firefox3','http://202.108.23.172','/m?word=mp3,http://www.slyizu.com/mymusic/VnV5WXtqXHxiV3ZrWnpnXXdrWHhrW3h9VnRkWXZtXHp1V3loWnlrXXZlMw$$.mp3,,[%B1%A7%BD%F4%C4%E3+%CF%F4%D1%C7%D0%F9]&ct=134217728&tn=baidusg,%B1%A7%BD%F4%C4%E3%20%20&si=%B1%A7%BD%F4%C4%E3;;%CF%F4%D1%C7%D0%F9;;0;;0&lm=16777216&sgid=1')
        selenium_get_value(sel1)
        selenium_capture_screenshot(sel1)
        sel1.stop()
        sel2=selenium_init('*firefox3','http://www.sina.com.cn','/')
        selenium_capture_entire_page_screenshot(sel2)
        sel2.stop()

    下载源代码seleniumtest.py

    几点注意事项:

    1)、在selenium-remote-control-1.0.3/selenium-python-client-driver-1.0.1/doc/selenium.selenium-class.html 中对Selenium支持的各种命令的说明,值得花点时间看看

    2)、在__init__(self, host, port, browserStartCommand, browserURL) 中,browserStartCommand为使用的浏览器,目前Selenium支持的浏览器对应参数如下:
    *firefox
    *mock
    *firefoxproxy
    *pifirefox
    *chrome
    *iexploreproxy
    *iexplore
    *firefox3
    *safariproxy
    *googlechrome
    *konqueror
    *firefox2
    *safari
    *piiexplore
    *firefoxchrome
    *opera
    *iehta
    *custom

    3)、capture_entire_page_screenshot目前只支持firefox、IE

    使用firefox时候使用capture_entire_page_screenshot比较简单,不需要特别设置,Selenium会自动处理。因此如果使用capture_entire_page_screenshot推荐使用firefox。

    IE必须运行在非HTA(non-HTA)模式下(browserStartCommand值为:*iexploreproxy ),并且需要安装http://snapsie.sourceforge.net/ 工具包,具体可以参考这篇文章:Using captureEntirePageScreenshot with Selenium

    转载请注明:出家如初,成佛有余 » Python中使用selenium作为Web Browser引擎

    发表我的评论
    取消评论

    表情

    Hi,您需要填写昵称和邮箱!

    • 昵称 (必填)
    • 邮箱 (必填)
    • 网址

    网友最新评论 (12)

    1. 哥啊,你那个命令“java –jar selenium-server.jar”在文中贴的时候,jar前面的减号是中文全角字符,这样复制粘贴后无法执行的,会误导小朋友的,请改正。
      zhengyun13年前 (2010-10-18)回复
    2. @zhengyuan :呵呵,谢谢提醒,已经更正
      chuanliang13年前 (2010-10-18)回复
    3. 测了一下,它与cPAMIE不同之处在于,它专门启动了一个Java语言开发的Server端,各种开发语言开发的client端只需要把请求(以及页面上选中元素、输入文字、点击按钮等输入和点击要求)发给Server端即可。不过,在Windows下测试很不顺畅,而且Server端也是启动一个浏览器,比如ie或firefox等,也不是说自己渲染,这点跟cPAMIE没啥大区别。
      zhengyun13年前 (2010-10-19)回复
    4. @zhengyun :如果不需要单独其浏览器,可以考虑# PythonWebKit、PyWebKitGtk、Python-Spidermonkey的方案,本质上也是利用webkit、spidermonkey的引擎来做的,只不过可以实现所谓的headless
      chuanliang13年前 (2010-10-19)回复
    5. 感谢楼主的分享,顶,顶,顶!!东SEO,www.dgseo163.com
      行云流水52013年前 (2010-10-21)回复
    6. Terrific work! This is the type of information that should be shared around the web. Shame on the search engines for not positioning this post higher!
      social workers13年前 (2010-11-14)回复
    7. 貌似几复杂,在windows下,还是喜欢直接使用'InternetExplorer.Application'方便,自己控制好,不喜欢用cPAMIE
      无聊13年前 (2011-01-13)回复
    8. Nice background, your posts were very good to read and it was something related to me.
      Elenore Punja13年前 (2011-01-25)回复
    9. non-HTA 在用这个IE模式的时候副脚本网站异步加载js有时会有问题,今天在用这种方式做自动化测试的似乎后由于页面是js动态加载的应用了大量的延迟加载和jquery的dom操作,结果页面卡住了,不知道大家有没有遇到过这个问题
      567813年前 (2011-06-03)回复
    10. Terrific work! This is the type of information that should be shared around the web. Shame on the search engines for not positioning this post higher!www.ftjxlsj.com
      林倪倪12年前 (2011-09-23)回复
    11. 虽然我不知道这说的是什么但我觉得楼主的水平挺高的,代码都一大堆,我这是做东莞电脑维修www.wangyezhizuo.org也许能修好硬件问题,代码的就搞不懂了
      小六子12年前 (2011-11-08)回复
    12. 这。。。 强悍!!想学下python,不知道怎么入门呢
      dvd12年前 (2011-11-16)回复