1.学习之前请下载chromedriver等之类的浏览器插件
""" 动态渲染页面页面抓取。 JavaScript除了可以Ajax直接获取数据之外,还可以通过计算生成,加密参数等形式 来更安全的获取数据。这些通过特别处理的数据我们很难找出规律直接Ajax去获取。 为了解决这些问题,我们可以直接使用模拟浏览器运行的方式来请求数据,这样可以 看到的是什么,抓取的源码就是什么,也可以避免去分析Ajax接口到底有什么参数。 Python提供的模拟浏览器运行的库:Selenium、Splash、PyV8等 """ """Selenium的用法解析 支持的浏览器Chrome、Firefox、PhantomJS还有Android、BlackBerry等手机端浏览器: browser = webdriver.Chrome() browser = webdriver.Firefox() browser = webdriver.Edge() browser = webdriver.PhantomJS() https://selenium-python.readthedocs.io/api.html webdriver的API解释 """ from selenium import webdriver # 可选择的浏览器 from selenium.webdriver.common.by import By # 选择器方法 from selenium.webdriver.common.keys import Keys # 键盘按键对应表 from selenium.webdriver.support import expected_conditions as EC from selenium.webdriver.support.wait import WebDriverWait # 声明浏览器对象并将其赋值为browser browser = webdriver.Chrome() try: # 调用get()方法请求网页 browser.get("https://www.baidu.com") # 调用find_element_by_id()方法查找输入节点ID input = browser.find_element_by_id("kw") # WebElement类型结果。调用此类下的send_keys()方法输入查找关键字 input.send_keys("Python") # 调用send_keys()输入键盘ENTER键 input.send_keys(Keys.ENTER) # 传入webdriver实例browser和超时时间 wait = WebDriverWait(browser, 10) # until()方法确认请求的结果不是False。presence_of_element_located()方法检查DOM上是否存在查询的该元素 wait.until(EC.presence_of_element_located((By.ID, "content_left"))) # 请求成功之后分别打印返回的当前url、cookies、网页源代码 print(browser.current_url) print(browser.get_cookies()) print(browser.page_source) finally: # 最后关闭浏览器 browser.close()
from selenium import webdriver import time # 获取chromedriver.exe路径 driver_path = r"E:\Program Files\chromedriver.exe" # 初始化一个driver,并且指定chromedriver的路径 driver = webdriver.Chrome(executable_path=driver_path) # 访问网页 driver.get("https://www.baidu.com/") # 通过page_source获取网页源代码 print(driver.page_source) # 等待5秒查看操作结果 time.sleep(5) # 关闭当前网页 driver.close() # 退出浏览器 driver.quit()
2.用selenium输入
"""通过Selenium API获取节点信息""" from selenium import webdriver from selenium.webdriver import ActionChains # 声明浏览器对象并将其赋值为browser browser = webdriver.Chrome() url = "https://zhihu.com/explore" # 调用get()方法请求网页 browser.get(url) # 通过ID属性找到对应节点 logo = browser.find_element_by_id("zh-top-link-logo") # 打印节点信息WebElement类型结果 print(logo) # 获取CSS中的class属性 print(logo.get_attribute("class")) # 获取节点文本信息 print(logo.text)
"""查找节点""" from selenium import webdriver from selenium.webdriver.common.by import By from selenium.webdriver.remote.webelement import WebElement # 包含所有节点查找方法 # 声明浏览器对象并将其赋值为browser browser = webdriver.Chrome() # 调用get()方法访问京东页面 browser.get("https://www.jd.com") """单个查找节点方法""" # 根据ID获取输入框 input_first = browser.find_element_by_id("key") # 根据CSS获取输入框 input_second = browser.find_element_by_css_selector("#key") # 根据XPath获取输入框 input_third = browser.find_element_by_xpath("//input[@id='key']") # 通用的函数查找版本,参数更灵活 input_fourth = browser.find_element(By.ID, "key") # 同样的WebElement类型结果 print(input_first, input_second, input_third, input_fourth) """多个查找节点方法""" # CSS选择器查找 lis = browser.find_elements(By.CSS_SELECTOR, ".cate_menu_item") # XPath查找 lis_first = browser.find_elements_by_xpath("//li[@class='cate_menu_item']") # 返回结果为列表,列表中的每个元素还是WebElement类型 print(lis, lis_first) # 关闭浏览器 browser.close()
from selenium import webdriver from selenium.webdriver.common.by import By from lxml import etree # 获取chromedriver.exe路径 driver_path = r"E:\Program Files\chromedriver.exe" # 初始化一个driver,并且指定chromedriver的路径 driver = webdriver.Chrome(executable_path=driver_path) # 访问网页 driver.get("https://www.baidu.com/") # 1.通过id输入文本 inputTag = driver.find_element_by_id("kw") # 2.第二种查找方式 inputTag = driver.find_elements(By.ID, "kw")[0] # 3.通过name输入文本 inputTag = driver.find_element_by_name("wd") # 4.通过属性输入文本 inputTag = driver.find_element_by_class_name("s_ipt") # 5.通过xpath输入文本 inputTag = driver.find_element_by_xpath("//input[@id='kw']") # 6.find_elements,后面添加s表示查找多个 inputTag = driver.find_elements_by_css_selector(".quickdelete-wrap > input")[0] # 输入文本必须使用send_keys inputTag.send_keys("python") # 特殊:查找标签和属性时可以使用lxml替代,因为lxml是C语言写的效率更高 html = etree.HTML(driver.page_source) html.xpath("")
3.用selenium表单提交
"""节点操作""" from selenium import webdriver import time # 声明浏览器对象并将其赋值为browser browser = webdriver.Firefox() # 调用get()方法请求网页 browser.get("https://www.jd.com") # XPath查找输入框 input = browser.find_element_by_xpath("//input[@id='key']") # 调用send_keys()方法输入文字 input.send_keys("华为") time.sleep(2) # 调用clear()方法清空输入的文字 input.clear() # 再次输入文字 input.send_keys("iPhone") # CSS查找button按钮 button = browser.find_element_by_css_selector(".button") # 调用click()方法点击按钮完成搜索 button.click()
from selenium import webdriver import time # 获取chromedriver.exe路径 driver_path = r"E:\Program Files\chromedriver.exe" # 初始化一个driver,并且指定chromedriver的路径 driver = webdriver.Chrome(executable_path=driver_path) # 访问网页 driver.get("https://www.baidu.com/") # 操作表单元素 inputTag = driver.find_element_by_id("kw") inputTag.send_keys("python") # 按钮点击 submitTag = driver.find_element_by_id("su") submitTag.click() time.sleep(5) # # 清除输入 inputTag.clear()
4.操作selenium完成百度搜索
"""动作链""" 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) # switch_to()方法将焦点切换到对应的选项,frame()方法通过索引、名称或webelement将焦点切换到指定的帧。 browser.switch_to.frame("iframeResult") # 通过ID找到需要的元素 source = browser.find_element_by_id("draggable") target = browser.find_element_by_id("droppable") # 声明ActionChains对象传入webdriver实例browser并赋值为actions变量 actions = ActionChains(browser) # 按住源元素上的鼠标左键,然后移动到目标元素并释放鼠标按钮。 actions.drag_and_drop(source, target) # perform()方法按顺序执行所有储存的操作。完成拖拽 actions.perform()
from selenium import webdriver from selenium.webdriver.common.action_chains import ActionChains # 获取chromedriver.exe路径 driver_path = r"E:\Program Files\chromedriver.exe" # 初始化一个driver,并且指定chromedriver的路径 driver = webdriver.Chrome(executable_path=driver_path) # 访问网页 driver.get("https://www.baidu.com/") # 行为链,完成百度搜索Python inputTag = driver.find_element_by_id("kw") # 找到输入框和按钮 submitBtn = driver.find_element_by_id("su") # 生成一个动作链对象 actions = ActionChains(driver) # 移动到输入框输入python actions.move_to_element(inputTag) actions.send_keys_to_element(inputTag, "python") # 移动到按钮点击按钮 actions.move_to_element(submitBtn) actions.click(submitBtn) # 执行所有存储在ActionChains中的动作 actions.perform()
5.操作selenium获取cookies
"""Cookies的获取和修改、删除""" from selenium import webdriver # 声明浏览器对象并将其赋值为browser browser = webdriver.Firefox() # 开始请求网页 browser.get("https://www.taobao.com") # 获取Cookies信息 print(browser.get_cookies()) # 添加cookie信息 browser.add_cookie({ "name": "yangyu", "domain": "www.taobao.com", "value": "germey"}) # 再次获取已添加cookie的列表,会包含两个cookies字典 print(browser.get_cookies()) # 删除所有Cookies信息 browser.delete_all_cookies() # 返回空列表 print(browser.get_cookies())
from selenium import webdriver # 获取chromedriver.exe路径 driver_path = r"E:\Program Files\chromedriver.exe" # 初始化一个driver,并且指定chromedriver的路径 driver = webdriver.Chrome(executable_path=driver_path) # 访问网页 driver.get("https://www.baidu.com/") # 获取所有cookies for cookie in driver.get_cookies(): print(cookie) # 获取对应的cookie print(driver.get_cookie("PSTM")) # 删除对应的cookie driver.delete_cookie("PSTM") print(driver.get_cookie("PSTM"))
6.操作selenium完成点击和页面等待
""" 目前,大多数Web应用程序都在使用AJAX技术。当浏览器加载页面时,该页面中的元素 可能以不同的时间间隔加载。这使定位元素变得困难:如果DOM中尚未存在元素,则 locate函数将引发ElementNotVisibleException异常。使用等待,我们可以解决这个 问题。等待在执行的操作之间提供了一些松弛 - 主要是使用元素定位元素或任何其他操作。 Selenium Webdriver提供两种类型的等待 - 隐式和显式。 1.显式等待使WebDriver等待某个条件发生,然后再继续执行。(建议使用显示等待) 显式等待是您定义的代码,用于在进一步执行代码之前等待某个条件发生。 这种情况的极端情况是time.sleep(),它将条件设置为等待的确切时间段。 提供了一些便捷方法,可帮助您编写仅在需要时等待的代码。 WebDriverWait与ExpectedCondition相结合是一种可以实现的方法。 title_is # 标题是某内容 title_contains # 标题包含某内容 presence_of_element_located # 节点加载出来,传人定位元组,如(By.ID ,'p') visibility_of_element_located # 节点可见,传人定位元组 visibility_of # 可见,传入节点对象 presence_of_all_elements_located # 所有节点加载出来 text_to_be_present_in_element # 某个节点文本包含某文字 text_to_be_present_in_element_value # 某个节点值包含某文字 frame_to_be_available_and_switch_to_it # 加载并切换 invisibility_of_element_located # 节点不可见 element_to_be_clickable # 节点可点击 staleness_of # 判断一个节点是否仍在DOM ,可判断页面是否已经刷新 element_to_be_selected # 节点可选择,传节点对象 element_located_to_be_selected # 节点可选择,传人定位元组 element_selection_state_to_be # 传人节点对象以及状态,相等返回True ,否则返回False element_located_selection_state_to_be # 传入定位元组以及状态,相等返回True ,否则返回False alert_is_present # 是否出现警告 """ 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 driver = webdriver.Firefox() # 调用get()方法请求网页 driver.get("https://www.taobao.com/") try: # WebDriverWait指定最长等待时间。而until()方法指定等待的条件 element = WebDriverWait(driver, 10).until( # 检查该元素是否在10秒内加载出来并成功返回。没有则抛出异常 EC.presence_of_element_located((By.ID, "q")) ) button = WebDriverWait(driver, 10).until( # 检查元素是否可以点击 EC.element_to_be_clickable((By.CSS_SELECTOR, ".btn-search")) ) print(element, button) finally: # 最后执行退出 driver.quit() """ 2.隐式等待使WebDriver在尝试定位元素时将DOM轮询一段时间。 隐式等待告诉WebDriver在尝试查找不能立即可用的任何元素(或元素) 时轮询DOM一段时间。默认设置为0.设置后,将为WebDriver对象的生命周期 设置隐式等待. 如果查找的节点没有立即出现,将会等待一段时间再次查找,这段时间是固定的, 而页面加载会受到网络条件的影响,是不固定因素 """ from selenium import webdriver # 声明浏览器对象并将其赋值为driver driver = webdriver.Firefox() # implicitly_wait()方法实现隐式等待。 driver.implicitly_wait(10) # 开始请求网页 driver.get("https://www.zhihu.com/explore") # 找到指定的元素 input = driver.find_element_by_id("zu-top-add-question") print(input)
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 # 获取chromedriver.exe路径 driver_path = r"E:\Program Files\chromedriver.exe" # 初始化一个driver,并且指定chromedriver的路径 driver = webdriver.Chrome(executable_path=driver_path) # 访问网页 driver.get("https://www.douban.com/") # 操作checkbox rememberBtn = driver.find_element_by_name("remember") # # 自动点击 rememberBtn.click() # 页面等待 # 1.隐式等待,傻傻等10秒 driver.implicitly_wait(10) driver.find_element_by_id("form_email") # 2.显示等待,获取到数据后立即结束等待 WebDriverWait(driver, 10).until( EC.presence_of_element_located((By.ID, "form_email")) )
7.操作selenium在同一个窗口中生成新页面
"""选项卡管理""" import time from selenium import webdriver # 声明浏览器对象并将其赋值为browser browser = webdriver.Chrome() # 开始请求网页 browser.get("https://www.baidu.com") # 调用execute_script()执行JavaScript()语句开启新选项卡 browser.execute_script("window.open()") # 获取选项卡列表 print(browser.window_handles) # 调用switch_to_window()方法切换选项卡 browser.switch_to_window(browser.window_handles[1]) # 在新选项卡里面请求网页 browser.get("https://www.jd.com") time.sleep(3) # 切换回原选项卡 browser.switch_to_window(browser.window_handles[0]) # 再次请求网页 browser.get("https://taobao.com")
"""Selenium API没有的操作,可以用execute_script()方法执行JavaScript语句解决""" from selenium import webdriver # 声明浏览器对象并将其赋值为browser browser = webdriver.Chrome() # 调用get()方法请求网页 browser.get("https://www.zhihu.com/explore") # 调用execute_script()方法在当前窗口/框架中同步执行JavaScript语句,下拉进度条 browser.execute_script("window.scrollTo(0, document.body.scrollHeight)") # 弹出alert提示框 browser.execute_script("alert('To Bottom')")
from selenium import webdriver # 获取chromedriver.exe路径 driver_path = r"E:\Program Files\chromedriver.exe" # 初始化一个driver,并且指定chromedriver的路径 driver = webdriver.Chrome(executable_path=driver_path) # 访问网页 driver.get("https://www.douban.com/") # 在同一个窗口中生成新的页面 driver.execute_script("window.open('https://www.douban.com/')") # 打印当前列表中有几个窗口,里面的对象就是窗口句柄 print(driver.window_handles) # 下标切换选中窗口 driver.switch_to_window(driver.window_handles[1]) # 打印当前url print(driver.current_url)
8.操作selenium选择选择框中数据
"""切换子框架、iframe,相当于页面的子页面。Selenium打开页面后,默认是在父级 的Frame里面操作,如果我们要切换到子页面,则需要使用switch_to.frame()方法切换 """ import time from selenium import webdriver from selenium.common.exceptions import NoSuchElementException # 声明浏览器对象并将其赋值为browser browser = webdriver.Chrome() url = "http://www.runoob.com/try/try.php?filename=jqueryui-api-droppable" # 调用get()方法请求网页 browser.get(url) # 切换到子frame browser.switch_to.frame("iframeResult") # try...except...语句处理和捕获异常 try: # 尝试获取父级CSS属性 logo = browser.find_element_by_class_name("logo") except NoSuchElementException as e: # 获取失败,打印失败信息 print("NO LOGO", e.args) # 切换到父级Frame browser.switch_to.parent_frame() # 获取父级的CSS属性 logo = browser.find_element_by_class_name("logo") # 打印获取的属性信息 print(logo) print(logo.text)
from selenium import webdriver from selenium.webdriver.support.ui import Select # 获取chromedriver.exe路径 driver_path = r"E:\Program Files\chromedriver.exe" # 初始化一个driver,并且指定chromedriver的路径 driver = webdriver.Chrome(executable_path=driver_path) # 操作select driver.get("http://www.dytt8.net/") selectBtn = Select(driver.find_element_by_name("field")) # 下标选择 selectBtn.select_by_index(2) # value选择 selectBtn.select_by_value("http://s.ygdy8.com/plus/so.php?typeid=19&keyword=") # 内容选择 selectBtn.select_by_visible_text("动漫")
9.操作selenium设置代理IP
from selenium import webdriver # 获取chromedriver.exe路径 driver_path = r"E:\Program Files\chromedriver.exe" # 设置代理IP options = webdriver.ChromeOptions() options.add_argument("--proxy-server=http://121.49.110.65:8888") # 初始化一个driver,并且指定chromedriver的路径 driver = webdriver.Chrome(executable_path=driver_path, chrome_options=options) driver.get("http://httpbin.org/ip")
10.操作selenium选择浏览器历史记录
"""前进forward()和后退back()""" import time from selenium import webdriver browser = webdriver.Chrome() browser.get("https://www.baidu.com") browser.get("https://www.taobao.com") browser.get("https://www.jd.com") # 在浏览器历史记录中向后退一步。 browser.back() time.sleep(3) # 在浏览器历史记录中向后前一步。 browser.forward() browser.close()