最近用selenium进行采集,遇到一些麻烦,对selenium的优缺点有了更深刻的理解。
先说说优点吧:
- 可视化界面,初学容易上手。
- 不深入理解动态加载和后端的交互也可以进行数据采集
- 比较符合普通人操作网页进行复制粘贴的习惯
缺点也很明显:
- 加载效率低,容易造成阻塞,采集效率也就不高
- 比较不易迁移,要适配没有界面的linux需要进行较多修改
- 可视化的采集容易遇到浏览器问题,比较不稳健
我相信所有的问题都是可以解决的,遇到以上问题完全是我个人能力问题。
上一篇博文对selenium进行了简单学习,今天再深入对几个遇到的问题进行了实战,本文主要针对页面要素加载的问题进行了整理。
通常selenium在采集的时候,就像我们访问页面一样,需要等待页面数据加载完成再进行采集,这个过程在selenium中是默认的,但是有些时候页面加载会遇到一些问题(比如内部某些js还没有加载完成),虽然采集到了数据,但是页面需要等待一段时间才能进行操作,同时也为了缓解访问服务器的压力,降低一些访问频率,通常可以采用time.sleep()和random结合来控制采集、刷新间隔。
查资料来看,解决加载问题的思路,通常有三种:
-
强制等待sleep
sleep(5) #打开页面以后等待5s
-
隐式等待implicitly_wait()
driver.implicitly_wait(10) #隐式等待10秒
由WebDriver提供的方法,一旦设置,这个隐式等待会在WebDriver对象实例的整个生命周期起作用,它不针对某一个元素,是全局元素等待,即在定位元素时,需要等待页面全部元素加载完成,才会执行下一个语句。如果超出了设置时间的则抛出异常。
可以理解为,页面不完成加载,他就等待或者超时报异常。
如果不这么设置,默认为implicitly_wait(0),当页面出现元素加载的时候就会进行采集,那么可能不一定能采集到我们的目标元素,从而导致一系列错误(可以参照以下链接)。
https://stackoverflow.com/questions/53588966/python-selenium-difference-between-driver-implicitly-wait-and-time-sleep
缺点:当页面某些js无法加载,但是想找的元素已经出来了,它还是会继续等待,直到页面加载完成(浏览器标签左上角圈圈不再转),才会执行下一句。某些情况下会影响脚本执行速度。
-
显式等待WebDriverWait()
显式等待可以针对某个特定元素设置加载等待时间
https://blog.csdn.net/sinat_41774836/article/details/88965281
wait = WebDriverWait(driver,10,0.5)
element =waite.until(EC.presence_of_element_located((By.ID,"kw"),message="")
# 此处注意,如果省略message='',则By.ID外面是两层();presence_of_element_located是定位方法和定位元素是否显示。
涉及到的包
from selenium import webdriver
import time
import random
from selenium.webdriver.support import expected_conditions
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.common.by import By