如何使用Selenium+PhantomJS抓取动态页面以及常见指令和问题

好多网站在发送请求后返回的并不是标准的html页面,而是需要执行一段js后才能获得页面

解决这个问题有多重方法,下面介绍的是使用selenium的方法+PhantomJS的方法。

1.环境

Python 2.7

Ubuntu16.04

2.安装

pip install selenium 

sudo apt-get install phantomjs  # 使用apt-get 安装的不完整,需要安装下面的包解决,也可以使用其他方法安装

sudo apt-get install nodejs 

sudo apt-get install nodejs-legacy

sudo apt-get install npm 

sudo npm -g install phantomjs-prebuilt

2.代码

# -*- coding:utf8 -*-
from selenium import webdriver
from selenium.webdriver.common.desired_capabilities import DesiredCapabilities
from lxml import etree

dcap = dict(DesiredCapabilities.PHANTOMJS)

# 设置浏览器Uesr-Agent
dcap[ "phantomjs.page.settings.userAgent"] = (
"Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/49.0.2623.221 Safari/537.36 SE 2.X MetaSr 1.0")

# 设置代理
service_args = [ '--proxy=127.0.0.1:8080', '--proxy-type=socks5']

# 禁止加载图片可以在一定程度上加快浏览器速度
dcap[ "phantomjs.page.settings.loadImages"] = False

dv = webdriver.PhantomJS(phantomjs_driver_path, desired_capabilities=dcap, service_args=service_args)

dv.get( "http://blog.csdn.net")
# print dv.page_source.encode('utf-8')


# 可以保存一张网页当前状态的图片
dv.get_screenshot_as_file( 'showcsdn.png')

# 设定最大等待时间
dv.set_page_load_timeout( 40)

# 设置脚本超时时间
dv.set_script_timeout( 10)

# 以下是常用命令

# 获取所有cookie
dv.get_cookies()


# 打印网页源码 ,根据实际情况选择编码方式,有的网站可能是gbk
print dv.page_source.decode( 'utf-8').encode( 'utf-8')

# 可以直接使用xpath在网页源码上进行结构化数据提取
html=etree.HTML(dv.page_source.encode( 'utf-8'))

print html.xpath( "//a[@class='s-user-name-top']//text()")

# 给指定元素传递参数
dv.find_element_by_xpath( "input_search" ).send_key( u 'python' )

dv.find_element_by_xpath( "//a[@class='btn-nobg-noborder btn-search']").click()
# dv.find_element_by_id('kw').send_keys(Keys.RETURN)

# 查找某元素,通过class_name
driver.find_element_by_class_name( 'input_search').send_key( u 'selemium')
# 检查某元素,通过id
driver.find_element_by_id( 'id')

# 打印当前网址
print driver.current_url

# 关闭当前的页面
driver.close()
# 关闭浏览器
driver.quit()

# 隐形等待

dv.implicitly_wait(30)

dv.get_screenshot_as_file( 'show_py.png')
# 解决错误
service_args=['--ignore-ssl-errors=true', '--ssl-protocol=TLSv1']




3.多进程的使用

from multiprocessing import Pool

pool = Pool(8)

data_list = pool.map(get, url_list)
pool.close()

pool.join()

4.找不到元素的问题

有时,phantomJS获得的页面源码的确存在某元素,但通过find_element_by_xpath()等定位函数却无法获得该元素对象,总是提示“元素不存在”的错误。遇到这种情况,除了检查元素节点路径是否正确外,还应该分析页面源码,检查元素是否被包裹在一个特定的frame中,如果是后者,那么在使用查找函数前,需要额外的处理。

比如网页源码中有如下代码:

<iframe id="topmenuFrame" width="100%" scrolling="no" height="100%" src="topmenu.aspx?>
<div id="haha">text</div>
</iframe>

假如你想要获取id="haha"的div标签,直接通过driver.find_element_by_id('haha')就会提示“元素不存在“的错误。

这时需要使用driver.switch_to_frame(driver.find_element_by_id``("topmenuFrame")),即先进入id为topmenuFrame的frame,然后再执行driver.find_element_by_id("haha"),就能正确获得该元素了。

需要注意的是,切换到这个frame之后,只能访问当前frame的内容,如果想要回到默认的内容范围,相当于默认的frame,还需要使用driver.switch_to_default_content()

页面中有多个frame时,要注意frame之间的切换。

五.三种等待方式

有些时候点击元素,如果元素还未加载完毕就点击会抛出异常。

这个时候需要等待网页加载完毕再继续执行代码

①强制等待

直接time.sleep(1)

②隐式等待

dv.implicitly_wait(10)

相当于让规定一定的加载时间,时间到了还没有加载完毕就报错

显示等待

相当于每隔一段时间检测一下。




猜你喜欢

转载自blog.csdn.net/cd_home/article/details/79413640
今日推荐