有的网页,不能直接通过wget,curl等命令、或者直接使用Python中的urllib,urllib2等这样的函数库来直接获取其真正展现给用户的信息,因为里面包含有JavaScript脚本(而该JS和页面数据的生成相关),需要通过Firefox、Chrome等浏览器渲染后才能得到想要看的结果。

 

例如,想查询的一个根据IP查询到地理位置的网页:http://www.ip.cn/125.95.26.81

为了写程序来自动获取我想要的数据,比如 http://www.ip.cn/125.95.26.81 中网页中的“广东省佛山市 电信”这几个字。一般来说,有如下两种方案:

1. 写Web UI自动化脚本,用Selenium启动真正的浏览器(如:IE、Firefox)来打开该网页,然后调用webdriver获取想要的页面元素。

2. 找一种浏览器渲染引擎,能够让其解析网页并执行网页中需要初始化JS,然后将JS、CSS等执行后的HTML代码输出出来。

启动真正的浏览器,可能带来两个问题:一个是需要的时间较长,另一个是UI自动化易受干扰、不够稳定。

而第2个方法,一时没有找到特别好的库(暂用Python语言)。

 

Selenium

Selenium 是一个用于Web应用程序测试的工具。Selenium测试直接运行在浏览器中,就像真正的用户在操作一样。支持的浏览器包括IE(7、8、9)、Mozilla Firefox、Mozilla Suite等。这个工具的主要功能包括:测试与浏览器的兼容性,测试你的应用程序看是否能够很好得工作在不同浏览器和操作系统之上。

Selenium 测试直接在浏览器中运行,就像真实用户所做的一样。Selenium 测试可以在 Windows、Linux 、Macintosh上的 Internet Explorer、Mozilla 、Firefox 中运行。其他测试工具都不能覆盖如此多的平台。使用 Selenium 和在浏览器中运行测试还有很多其他好处。下面是主要的两大好处:

1)通过编写模仿用户操作的 Selenium 测试脚本,可以从终端用户的角度来测试应用程序。

2)通过在不同浏览器中运行测试,更容易发现浏览器的不兼容性。

Selenium 的核心,也称browser bot,是用 JavaScript 编写的,这使得测试脚本可以在受支持的浏览器中运行。browser bot 负责执行从测试脚本接收到的命令,测试脚本要么是用 HTML 的表布局编写的,要么是使用一种受支持的编程语言编写的。

 

Selenium 下载安装

Selenium 官方下载: selenium-2.42.1.tar.gz

Selenium 安装步骤: selenium install

Selenium 实例(自己写的,测试成功)

通过FireFox打开网页  并渲染完毕后,获取正文内容(Ubuntu 12.04 + Firefox)

#!/usr/bin/env python
# -*- coding:utf-8 -*-
#
# author: sunboy_2050
# blog: https://blog.mimvp.com

from selenium import webdriver

import sys
reload(sys)
sys.setdefaultencoding('utf8')

def spider_url_content(url):
    try:
        browser = webdriver.Firefox()       # 打开 FireFox 浏览器
    
#         chromeDriverDir = '/usr/bin/google-chrome'
#         browser = webdriver.Chrome(executable_path=chromeDriverDir)        # 打开 Chrome 浏览器
    
        browser.get(url)                
        content = browser.find_element_by_id('container')       # 通过标记id 获取网页的内容
        content = content.text
        
        browser.quit()                      # 关闭浏览器
        
        print("content: " + content)
        
    except Exception as ex:
        print("error msg: " + str(ex))

if __name__ == '__main__':
    url = 'https://blog.mimvp.com'
    spider_url_content(url)

 

抓取示例

根据网上的一些方案和请教同事,最后在Selenium webdriver中找到了不启动浏览器,但是带基于Webkit引擎的名为“PhantomJS”的driver。后来找资料发现,LinkedIn、Twitter等知名互联网公司也在使用PhantomJS用于测试

对于PhantomJS的好处,可阅读:http://phantomjs.org/ (Headless Website Testing, Screen Capture,Page Automation, Network Monitoring)

对于哪些情况下不适合用PhantomJS而应该用真正的Browser,可阅读:http://www.chrisle.me/2013/08/5-reasons-i-chose-selenium-over-phantomjs/

这里就不专门说PhantomJS的优劣势了,不过,它能解决我当前的问题。

先通过官方网站下载PhantomJS的可执行文件即可;然后像正常写Selenium自动化脚本一样来做即可。

一个示例程序如下:

#!/usr/bin/python
# -*- coding: utf-8 -*-
 
'''
Created on Dec 6, 2013
 
@author: Jay <smile665@gmail.com>
@description: use PhantomJS to parse a web page to get the geo info of an IP
'''
 
from selenium import webdriver
 
import sys
reload(sys)
sys.setdefaultencoding('utf-8')
 
driver = webdriver.PhantomJS(executable_path='./phantomjs')  #这要可能需要制定phatomjs可执行文件的位置
driver.get("http://www.ip.cn/125.95.26.81")
#print driver.current_url
#print driver.page_source
print driver.find_element_by_id('result').text.split('\n')[0].split('来自:')[1]
driver.quit

运行结果:

jay@jay-linux:~/workspace/python_test$ python try_phantomjs.py
广东省佛山市 电信

当然,刚好目前的Selenium(2.38.2)和PhontomJS(1.9.2)一起用有bug,见我另一篇文章:Selenium 2.38.2 和 PhantomJS 1.9.2 一起使用的一个Bug

 

参考资料:

很好的入门指引:http://www.realpython.com/blog/python/headless-selenium-testing-with-python-and-phantomjs/

 

官方说明:

https://github.com/detro/ghostdriver

http://phantomjs.org/

http://phantomjs.org/users.html

一个和PhantomJS类似的东东,不过它基于Gecko而不是Webkit:http://slimerjs.org/

这里有位兄台也使用PhantomJS抓取数据,可以看一下:http://blog.chinaunix.net/uid-22414998-id-3692113.html