PhantomJS+Selenium小记

前沿:接触PhantomJS本意是为了通过树莓派抓取dota2每日特价的页面,然后邮件推送信息,在此记录下相关学习笔记。

一. PhantomJS编译安装

为了使用最新的PhantomJS,我通过官方的编译教程,在树莓派上编译安装最新版。

  1. 依赖包安装

    • debian系操作系统:
      #apt-get install build-essential g++ flex bison gperf ruby perl \
      libsqlite3-dev libfontconfig1-dev libicu-dev libfreetype6 libssl-dev \
      libpng-dev libjpeg-dev python libx11-dev libxext-dev
    • centos操作系统:

      #yum -y install gcc gcc-c++ make flex bison gperf ruby \
      openssl-devel freetype-devel fontconfig-devel libicu-devel sqlite-devel \
      libpng-devel libjpeg-devel

      由于树莓派使用的是raspbian系统,所以使用了debian的依赖包安装

  2. 源码下载及编译

    git clone git://github.com/ariya/phantomjs.git
    git下载完成后进入phantomjs源码目录
    cd phantomjs
    检查及下载一些依赖包
    git checkout 2.1.1
    git submodule init
    git submodule update
    开始编译安装
    python3 build.py --jobs 2

    由于默认使用4核心来编译PhantomJS,而我为了在编译过程中保障树莓派的稳定运行,所以使用–jobs 2指定使用2核心编译,结果就是编译的时间变长了。。。。
    NOTICE:为了保障编译环境的干净,推荐复制一份phantomjs源码,当编译过程中出现问题后使用备份的源码再重新编译,避免由于某些临时垃圾导致的编译问题(我在这上面坑了一天。。。后来是直接从头再来就编译成功了)

编译成功后会在phantomjs/bin目录下存在一个phantomjs的可执行文件

  • 查看版本号:
    ./phantomjs -v 
    2.1.1
  • 放置到相关目录下
    cp phantomjs/bin/phantomjs /usr/bin

    至此,phantomjs已经配置完成。

二. selenium使用

通过selenium,可以控制firefox、IE、CHROME、PhantomJS对网页进行一些操作,我这里主要通过PhantomJS来实现一些动态网页的内容加载。

  1. 一般操作流程分析:

    from time import sleep
    from selenium import webdriver
    driver = webdriver.PhantomJS(executable_path='/usr/bin/pahantomjs')
    driver.get('http://www.baidu.com')
    sleep(3)
    driver.quit()

    这是一个简单的自动打开百度的代码,如果需要使用firefox操作,则只需要将webdriver.PhantomJS修改为webdriver.Firefox()就可以了。当然,本代码推荐使用firefox方式打开,这样才能看到效果。

  2. 页面元素的定位方法汇总

    1. 单个元素返回
      • 通过id属性来定位元素

        find_element_by_id('xx')

      • 通过name属性来定位元素

        find_element_by_name('xx')

      • 通过class属性来定位元素

        find_element_by_class_name('xx')

      • 通过元素的标签名来定位元素

        find_element_by_tag_name('xx')

      • 通过link的文本内容定位元素

        find_element_by_link_text('xx')

      • 通过link的部分文本内容定位元素

        find_element_by_partial_link_text('xx')

    2. 多元素返回
      返回的是一个列表,可以通过for循环处理
      • find_elements_by_id('xx')
      • find_elements_by_name('xx')
      • find_elements_by_class_name('xx')
      • find_elements_by_tag_name('xx')
      • find_elements_by_link_text('xx')
    3. XPath方法查找
      XPath方式其实就相当于通过tag方式来查找,不过功能更强悍
       find_element_by_xpath('/html/body/div/div[2]/div/from/span/input')

      按照顺序,一路找到input,其中div[2]表示当前层级下的第二个div标签

       find_element_by_xpath('//input[@id='kw']')

      //表示当前页面某目录下,input表示定位元素的标签名,[@id='kw']表示这个元素的id属性值等于kw
      当然,属性值之间还是用逻辑运算符and来连接两个条件

       find_element_by_xpath('//input[@id='kw' and @class='su']/span/input')
    4. 用By定位元素
      以上所有的元素定位方法,都是通过统一调用find_element()方法实现的,都可以通过By来实现

       from selenium import webdriver
       from selenium.webdriver.common.by import By
       find_element(By.ID,'xx')
       find_element(By.NAME,'xx')
       find_element(By.CLASS_NAME,'xx')
       find_element(By.TAG_NAME,'XX')
       find_element(By.LINK_TEXT,'xx')
       find_element(By.PARTIAL_LINK_TEXT,'xx')
       find_element(By.XPATH,'//*[@class='xx']')
  3. 一些简单操作

    1. 页面操作
      • 后退

        driver.back()

      • 前进

        driver.forward()

      • 刷新

        driver.refresh()

    2. 元素的方法
    • 清除文本

      clear()

    • 模拟按键输入

      send_keys('selenium')

    • 单击某个元素

      click()

    • 表单提交(回车)

      submit()

    • 返回元素的尺寸

      size

    • 获取元素的文本

      text

    • 获取属性值

      get_attribute(name)

前进、后腿、刷新示例代码:

from time import sleep
from selenium import webdriver

driver = webdriver.Firefox()

first_url = 'http://www.baidu.com'
driver.get(first_url)
sleep(3)
second_url = 'http://news.baidu.com'
driver.get(second_url)
driver.back()
sleep(3)
driver.forward()
sleep(3)
driver.refresh()
sleep(3)
driver.quit()

元素的操作示例:

from selenium import webdriver

driver = webdriver.Firefox()
driver.get('http://www.baidu.com')
#返回百度页面底部备案信息
text = driver.find_element_by_id('cp').text
print(text)

#返回元素的属性值
attribute = driver.find_element_by_id('kw').get_attribute('type')
print(attribute)

driver.quit()

后记

至此,已经能够通过selenium+phantomjs对动态页面进行操作了,从此爬虫更吊了。。。写了个爬取豆瓣电影高分的简单爬虫,有兴趣的可以看看

#!/usr/bin/env python3
#coding=utf-8
#豆瓣高分电影爬取

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

driver = webdriver.PhantomJS(executable_path='/usr/bin/phantomjs')
driver.get('https://movie.douban.com/explore#!type=movie&tag=%E8%B1%86%E7%93%A3%E9%AB%98%E5%88%86')

print('starting to get filename')
try:
    while True:
        element = WebDriverWait(driver,60).until(EC.presence_of_element_located((By.LINK_TEXT,'加载更多')))
        print('加载更多出现')
        element.click()
except:
    print('加载完成')

movielist = driver.find_elements_by_xpath("//div[@class='list']/a")
for i in movielist:
    print(i.find_element_by_tag_name('p').text)

driver.close()

NOTICE:浏览器会对URL自动encode,如果在phantomjs中的url地址含有中文,则需要手动urlencode下,不然会无效。
最后,推荐一本书《selenium2自动化测试实战-基于python语言》,我的selenium的相关操作和部分示例代码都是上面贴过来的,感觉不错的一本书。

发表评论

电子邮件地址不会被公开。 必填项已用*标注