Selenium+PhantomJS爬虫之路

故事扮演 提交于 2019-12-25 22:04:33

【推荐】2019 Java 开发者跳槽指南.pdf(吐血整理) >>>

爬虫三剑客:python--手 selenium--剑柄 phantomjs--剑尖

Selenium

一、简介

Selenium是一个自动化测试工具,支持包括Chrome,Firefox,Safari,PhantomJs等一些浏览器。如果用于爬虫中,我们主要用来解决一些JavaScript渲染的问题。

我们在使用Requests库去请求一些网页的时候,比如 163music,我们获得的响应数据呢,并不全是我们在浏览器中看到的信息。他可能是通过js渲染出来的。那么,我们如果使用Selenium库,就不会再去关心如何去解决这种问题了。 因为我们的浏览器,比如PhantomJs,他就是一个无界面的浏览器,他用来渲染解析js,而Selenium库就负责给浏览器发送一些命令,模拟一些比如下拉,拖拽,翻页,输入表单等动作。这样他们两个结合,对于那些 JS 的渲染问题是不是完美解决了。

注意:

虽然Selenium库加上PhantomJs很好用,但是他毕竟是驱动一个浏览器,然后获取数据。所以在我们使用中,会发现他并没有我们使用一些解析库速度快。这其实就是他的弊端,所以我还是建议大家,不到实在找不到解决办法的时候,不去使用他们。

二、安装

Windows

第一种方法是:下载源码安装,下载地址(https://pypi.python.org/pypi/selenium)解压并把整个目录放到C:\Python27\Lib\site-packages下面

第二种方法是:可以直接在C:\Python27\Scripts 下输入命令安装 pip install -U selenium

linux

pip3 install selenium

PhantomJS

一、简介

PhantomJS 是一个基于 WebKit(WebKit是一个开源的浏览器引擎,Chrome,Safari就是用的这个浏览器引擎) 的服务器端 JavaScript API,相当于一个无界面的浏览器,主要应用场景是:无需浏览器的 Web 测试,页面访问自动化,屏幕捕获,网络监控

二、安装

Windows

下载源码安装,下载地址(http://phantomjs.org/download.html)解压并把解压缩的路径添加到环境变量中即可,我自己的放到了C:\Python27\Scripts 下面

Linux

sudo apt-get install PhantomJS

浏览器驱动的安装:

Chrome浏览器驱动

PhantomJs浏览器驱动

我们需要把安装好的浏览器驱动配置到我们的环境变量。对于Windows用户,配置环境变量比较麻烦。我们需要找到下载好的驱动位置,然后复制他的文件位置,见他粘贴到环境变量即可。

配置完成,命令行输入:

phantomjs -v

查看是否成功。

Selenium + PhantomJS + python 简单实现爬虫的功能

python可以使用selenium执行javascript,selenium可以让浏览器自动加载页面,获取需要的数据。selenium自己不带浏览器,可以使用第三方浏览器如Firefox,Chrome等,也可以使用headless浏览器如PhantomJS在后台执行。 在工作用遇到一个问题,当加载一个手机端的URL时候,会加载不上,需要我们在请求头中设置一个User-Agent,设置完以后就可以打开了(Windows下执行,linux下执行的话就不用加executable_path='C:\Python27\Scripts\phantomjs.exe')

phantomjs:

from selenium import webdriver
from selenium.webdriver.common.desired_capabilities import DesiredCapabilities
  
dcap = dict(DesiredCapabilities.PHANTOMJS) #设置userAgent
dcap["phantomjs.page.settings.userAgent"] = ("Mozilla/5.0 (Macintosh; Intel Mac OS X 10.9; rv:25.0) Gecko/20100101 Firefox/25.0 ")
  
obj = webdriver.PhantomJS(executable_path='C:\Python27\Scripts\phantomjs.exe',desired_capabilities=dcap) #加载网址
obj.get('http://wap.95533pc.com')#打开网址
obj.save_screenshot("1.png") #截图保存
obj.quit() # 关闭浏览器。当出现异常时记得在任务浏览器中关闭PhantomJS,因为会有多个PhantomJS在运行状态,影响电脑性能

Chrome:

from selenium import webdriver
#webdriver可以认为是浏览器的驱动器,要驱动浏览器必须用到webdriver,支持多种浏览器,这里以Chrome为例
browser = webdriver.Chrome()
二、访问页面并获取网页html
from selenium import webdriver
browser = webdriver.Chrome()
browser.get('https://www.taobao.com')
print(browser.page_source)#browser.page_source是获取网页的全部html
browser.close()

超时设置

webdriver类中有三个和时间相关的方法:

  1. set_page_load_timeout 设置页面完全加载的超时时间,完全加载即完全渲染完成,同步和异步脚本都执行完
  2. setScriptTimeout 设置异步脚本的超时时间
  3. implicitly_wait 识别对象的智能等待时间

下面我们以获取校花网title为例来验证效果,因为校花网中图片比较多,所以加载的时间比较长,更能时间我们的效果


from selenium import webdriver
obj = webdriver.PhantomJS(executable_path="D:\Python27\Scripts\phantomjs.exe")
obj.set_page_load_timeout(5)
try:
 obj.get('http://www.xiaohuar.com')
 print obj.title
except Exception as e:
 print e 
 

元素的定位

对象的定位是通过属性定位来实现的,这种属性就像人的身份证信息一样,或是其他的一些信息来找到这个对象,那我们下面就介绍下Webdriver提供的几个常用的定位方法

常用的查找方法

  • find_element_by_id
  • find_element_by_name
  • find_element_by_xpath
  • find_element_by_link_text
  • find_element_by_partial_link_text
  • find_element_by_tag_name
  • find_element_by_class_name
  • find_element_by_css_selector

<input id="kw" name="wd" class="s_ipt" value="" maxlength="255" autocomplete="off">

上面这个是百度的输入框,我们可以发现我们可以用id来定位这个标签,然后就可以进行后面的操作了

from selenium import webdriver

obj = webdriver.PhantomJS(executable_path="D:\Python27\Scripts\phantomjs.exe")
obj.set_page_load_timeout(5)
try:
    obj.get('http://www.baidu.com')
    obj.find_element_by_id('kw')  # 通过ID定位
    obj.find_element_by_class_name('s_ipt')  # 通过class属性定位
    obj.find_element_by_name('wd')  # 通过标签name属性定位
    obj.find_element_by_tag_name('input')  # 通过标签属性定位
    obj.find_element_by_css_selector('#kw')  # 通过css方式定位
    obj.find_element_by_xpath("//input[@id='kw']")  # 通过xpath方式定位
    obj.find_element_by_link_text("贴吧")  # 通过xpath方式定位

    print obj.find_element_by_id('kw').tag_name  # 获取标签的类型
except Exception as e:
    print (e) 

也可以使用通用的方法:

from selenium import webdriver
from selenium.webdriver.common.by import By ---这里需要记住By模块所以需要导入
browser = webdriver.Chrome()
browser.get('https://www.taobao.com')
input_first = browser.find_element(BY.ID,'q')#第一个参数传入名称,第二个传入具体的参数
print(input_first)
browser.close()

多个元素,elements多个s

input_first = browser.find_elements_by_id('q')

浏览器的操作

1、调用启动的浏览器不是全屏的,有时候会影响我们的某些操作,所以我们可以设置全屏

from selenium import webdriver

obj = webdriver.PhantomJS(executable_path="D:\Python27\Scripts\phantomjs.exe")
obj.set_page_load_timeout(5)
obj.maximize_window()  # 设置全屏
try:
    obj.get('http://www.baidu.com')
    obj.save_screenshot('11.png')  # 截取全屏,并保存
except Exception as e:
    print (e)

2、设置浏览器宽、高

from selenium import webdriver

obj = webdriver.PhantomJS(executable_path="D:\Python27\Scripts\phantomjs.exe")
obj.set_page_load_timeout(5)
obj.set_window_size('480', '800')  # 设置浏览器宽480,高800
try:
    obj.get('http://www.baidu.com')
    obj.save_screenshot('12.png')  # 截取全屏,并保存
except Exception as e:
    print (e)

3、操作浏览器前进、后退

from selenium import webdriver

obj = webdriver.PhantomJS(executable_path="D:\Python27\Scripts\phantomjs.exe")
try:
    obj.get('http://www.baidu.com')  # 访问百度首页
    obj.save_screenshot('1.png')
    obj.get('http://www.sina.com.cn')  # 访问新浪首页
    obj.save_screenshot('2.png')
    obj.back()  # 回退到百度首页
    obj.save_screenshot('3.png')
    obj.forward()  # 前进到新浪首页
    obj.save_screenshot('4.png')
except Exception as e:
    print (e) 

元素交互操作-搜索框传入关键词进行自动搜索

定位到元素以后,我们就应该对相应的对象进行某些操作,以达到我们某些特定的目的,那我们下面就介绍下Webdriver提供的几个常用的操作方法

from selenium import webdriver

obj = webdriver.PhantomJS(executable_path="D:\Python27\Scripts\phantomjs.exe")
obj.set_page_load_timeout(5)
try:
    obj.get('http://www.baidu.com')
    print
    obj.find_element_by_id("cp").text  # 获取元素的文本信息
    obj.find_element_by_id('kw').clear()  # 用于清除输入框的内容
    obj.find_element_by_id('kw').send_keys('Hello')  # 在输入框内输入Hello
    obj.find_element_by_id('su').click()  # 用于点击按钮
    obj.find_element_by_id('su').submit()  # 用于提交表单内容

except Exception as e:
    print (e)

交互动作,驱动浏览器进行动作,模拟拖拽动作,将动作附加到动作链中串行执行

from selenium import webdriver
from selenium.webdriver import ActionChains#引入动作链

browser = webdriver.Chrome()
url = 'http://www.runoob.com/try/try.php?filename=jqueryui-api-droppable'
browser.get(url)
browser.switch_to.frame('iframeResult')#切换到iframeResult框架
source = browser.find_element_by_css_selector('#draggable')#找到被拖拽对象
target = browser.find_element_by_css_selector('#droppable')#找到目标
actions = ActionChains(browser)#声明actions对象
actions.drag_and_drop(source, target)
actions.perform()#执行动作

键盘事件

1、键盘按键用法

from selenium.webdriver.common.keys import Keys

obj = webdriver.PhantomJS(executable_path="D:\Python27\Scripts\phantomjs.exe")
obj.set_page_load_timeout(5)
try:
    obj.get('http://www.baidu.com')
    obj.find_element_by_id('kw').send_keys(Keys.TAB)  # 用于清除输入框的内容,相当于clear()
    obj.find_element_by_id('kw').send_keys('Hello')  # 在输入框内输入Hello
    obj.find_element_by_id('su').send_keys(Keys.ENTER)  # 通过定位按钮,通过enter(回车)代替click()

except Exception as e:
    print (e) 

2、键盘组合键使用

from selenium import webdriver
from selenium.webdriver.common.keys import Keys

obj = webdriver.PhantomJS(executable_path="D:\Python27\Scripts\phantomjs.exe")
obj.set_page_load_timeout(5)
try:
    obj.get('http://www.baidu.com')
    obj.find_element_by_id('kw').send_keys(Keys.TAB)  # 用于清除输入框的内容,相当于clear()
    obj.find_element_by_id('kw').send_keys('Hello')  # 在输入框内输入Hello
    obj.find_element_by_id('kw').send_keys(Keys.CONTROL, 'a')  # ctrl + a 全选输入框内容
    obj.find_element_by_id('kw').send_keys(Keys.CONTROL, 'x')  # ctrl + x 剪切输入框内容

except Exception as e:
    print(e)

中文乱码问题

selenium2 在python的send_keys()中输入中文会报错,其实在中文前面加一个u变成unicode就能搞定了

鼠标事件

1、鼠标右击

from selenium import webdriver
from selenium.webdriver.common.action_chains import ActionChains

obj = webdriver.PhantomJS(executable_path="D:\Python27\Scripts\phantomjs.exe")
try:
    obj.get("http://pan.baidu.com")
    obj.find_element_by_id('TANGRAM__PSP_4__userName').send_keys('13201392325')  # 定位并输入用户名
    obj.find_element_by_id('TANGRAM__PSP_4__password').send_keys('18399565576lu')  # 定位并输入密码
    obj.find_element_by_id('TANGRAM__PSP_4__submit').submit()  # 提交表单内容
    f = obj.find_element_by_xpath('/html/body/div/div[2]/div[2]/....')  # 定位到要点击的标签
    ActionChains(obj).context_click(f).perform()  # 对定位到的元素进行右键点击操作

except Exception as e:
    print(e) 

2、鼠标双击

from selenium import webdriver
from selenium.webdriver.common.action_chains import ActionChains

obj = webdriver.PhantomJS(executable_path="D:\Python27\Scripts\phantomjs.exe")
try:
    obj.get("http://pan.baidu.com")
    obj.find_element_by_id('TANGRAM__PSP_4__userName').send_keys('13201392325')  # 定位并输入用户名
    obj.find_element_by_id('TANGRAM__PSP_4__password').send_keys('18399565576lu')  # 定位并输入密码
    obj.find_element_by_id('TANGRAM__PSP_4__submit').submit()  # 提交表单内容
    f = obj.find_element_by_xpath('/html/body/div/div[2]/div[2]/....')  # 定位到要点击的标签
    ActionChains(obj).double_click(f).perform()  # 对定位到的元素进行双击操作

except Exception as e:
    print (e) 

Frame框架

有些网页在我们直接使用Selenium驱动浏览器打印源码的时候,并没有如期获得想要的数据,那在我们查看网页源码的时候,可以看到网页的iframe标签包裹的一个一个的框架。那么这就需要我们请求对应框架,拿到源码了。

from selenium import webdriver
browser = webdriver.Chrome()
browser.get('https://music.163.com/#/discover/artist/signed/')
#请求框架内容
browser.switch_to.frame('contentFrame')
print(browser.page_source)

cookie

使用selenium还可以对cookie进行操作,获取,添加,删除cookie:

from selenium import webdriver

driver = webdriver.Chrome()
driver.get('https://www.zhihu.com/explore')
# 获取cookie
print(driver.get_cookies())
# 添加cookie
driver.add_cookie({'name': 'name', 'domain': 'www.zhihu.com', 'value': 'germey'})
# 删除cookie
driver.delete_all_cookies()

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!