最新需要帮一个同事爬一个网站的数据,但是这个网站的页面跳转都是做的ts跳转并没有明文链接,而且uri也是全部被replce了的,所以用request做不了,只能老老实实用selenium模仿用户点击去爬了,虽然要慢一些。
https://blog.csdn.net/qq_43965708/article/details/120658713
https://zhuanlan.zhihu.com/p/111859925
环境准备
首先肯定是安装selenium
pip install selenium
然后是安装驱动,根据自己的浏览器和版本选择驱动进行下载。
Firefox浏览器驱动:geckodriver
Chrome浏览器驱动:chromdriver
IE浏览器驱动:IEDriverServer
Edge浏览器驱动:MicrosoftWebDriver
Opera浏览器驱动:operadriver
PhantomJS浏览器驱动:phantomjs
代码
我是用的是chrom 101版本,所以驱动也是101的
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC
import pandas as pd
import time
target = 'https://..........'
option = webdriver.ChromeOptions()
option.add_argument('headless')
driver = webdriver.Chrome('C:\damien\software\chromedriver\chromedriver.exe',chrome_options=option)
driver.get(target)
关于ChromeOptions可以参考这篇Blog
接下来呢就是关于页面dom选取,类似js或者ts的jquery的用css选取方式。
driver.find_element(by=By.XPATH,value='//*[@id=\"' + contentId +'\"]')
我一般使用的XPATH的方式去选取。还有就是find_element只会返回一个元素,find_elements则会返回数组。
还有就是一些基本操作 例如浏览器的前进后退和刷新
driver.forward()
driver.back()
driver.refresh()
还有就是例如表单的输入与提交
driver.find_element(by=By.XPATH,value='//*[@id=\"...."]').clear() driver.find_element(by=By.XPATH,value='//*[@id=\"...\"]').send_keys("selenium")
driver.find_element(by=By.XPATH,value='//*[@id=\"...\"]').click()
还有获取一些其他属性
driver.find_element(by=By.XPATH,value='//*[@id=\"...\"]').size # 返回元素的尺寸
driver.find_element(by=By.XPATH,value='//*[@id=\"...\"]').text # 获取元素的文本
driver.find_element(by=By.XPATH,value='//*[@id=\"...\"]').get_attribute('someAttr') # 获得属性值
driver.find_element(by=By.XPATH,value='//*[@id=\"...\"]').is_displayed() # 设置该元素是否用户可见
还有个比较重要的 就是等待某个dom加载完成
显式等待使WebdDriver等待某个条件成立时继续执行,否则在达到最大时长时抛出超时异常(TimeoutException)。
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.Chrome()
driver.get("......")
element = WebDriverWait(driver, 5, 0.5).until(
EC.presence_of_element_located((By.ID, "......"))
)
element.send_keys('......')
WebDriverWait类是由WebDirver 提供的等待方法。在设置时间内,默认每隔一段时间检测一次当前页面元素是否存在,如果超过设置时间检测不到则抛出异常。具体格式如下:
WebDriverWait(driver, timeout, poll_frequency=0.5, ignored_exceptions=None)
- driver :浏览器驱动。
- timeout :最长超时时间,默认以秒为单位。
- poll_frequency :检测的间隔(步长)时间,默认为0.5S。
- ignored_exceptions :超时后的异常信息,默认情况下抛NoSuchElementException异常。
- WebDriverWait()一般由until()或until_not()方法配合使用,下面是until()和until_not()方法的说明。
- until(method, message=‘’) 调用该方法提供的驱动程序作为一个参数,直到返回值为True。
- until_not(method, message=‘’) 调用该方法提供的驱动程序作为一个参数,直到返回值为False。
还有一种是隐式等待,如果某些元素不是立即可用的,隐式等待是告诉WebDriver去等待一定的时间后去查找元素。 默认等待时间是0秒,一旦设置该值,隐式等待是设置该WebDriver的实例的生命周期。
from selenium import webdriver
driver = webdriver.Chrome()
driver.implicitly_wait(10) # seconds
driver.get(".....")
myDynamicElement = driver.find_element(by=By.XPATH,value='//*[@id=\"...\"]')
还有就是刚才用过的ES,用作元素判断。可以参考这篇blog