好多网站在发送请求后返回的并不是标准的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.代码
# 隐形等待
dv.implicitly_wait(30)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)
相当于让规定一定的加载时间,时间到了还没有加载完毕就报错
显示等待
相当于每隔一段时间检测一下。