Python+Selenium——自动填写网页表格程序

这是一个用来更新公园信息的数据管理系统,而截图这个页面主要是用来更新site信息的,幸运的是这个页面的每个元素都可以用ID来定位。其中包含三种形式的信息:文本框,下拉列表和复选按钮。我的实现思路是把ID对应定位信息放在excel表格里,通过抓取excel表里提供的定位信息和所对应的需要更新的值进行数据更新。
这里分别对文本框信息输入,下拉列表选择和复选按钮勾选做了封装处理,再把相应的方法统一放到update方法来实现。这样就不需要再对每个字段进行单独处理了。
Python+Selenium——自动填写网页表格程序_第1张图片
封装代码:

from selenium.webdriver.support.ui import Select
from selenium.common.exceptions import NoSuchElementException, TimeoutException
import traceback
import time


class BasePage:
	def __init__(self, driver):
		self.driver = driver

    # 对查找单个页面元素进行封装。
	def find_element(self, by, locator):
		by = by.lower()
		element = None
		if by in ['id', 'name', 'xpath', 'class', 'tag', 'link', 'plink']:
			try:
				if by == 'id':
					element = self.driver.find_element_by_id(locator)
				elif by == 'name':
					element = self.driver.find_element_by_name(locator)
				elif by == 'xpath':
					element = self.driver.find_element_by_xpath(locator)
				elif by == 'class':
					element = self.driver.find_element_by_class_name(locator)
				elif by == 'tag':
					element = self.driver.find_element_by_tag_name(locator)
				elif by == 'link':
					element = self.driver.find_element_by_link_text(locator)
				elif by == 'plink':
					element = self.driver.find_element_by_partial_link_text(locator)
				else:
					print('Not find the element "{}"!'.format(locator))
				return element
			except NoSuchElementException as e:
				print(traceback.print_exc())
		else:
			print('Provided a wrong locator "{}"!'.format(locator))
			
    # 对查找多个页面元素进行封装。
	def find_elements(self, by, locator):
		by = by.lower()
		elements = None
		if by in ['id', 'name', 'xpath', 'class', 'tag', 'link', 'plink']:
			try:
				if by == 'id':
					elements = self.driver.find_elements_by_id(locator)
				elif by == 'name':
					elements = self.driver.find_elements_by_name(locator)
				elif by == 'xpath':
					elements = self.driver.find_elements_by_xpath(locator)
				elif by == 'class':
					elements = self.driver.find_elements_by_class_name(locator)
				elif by == 'tag':
					elements = self.driver.find_elements_by_tag_name(locator)
				elif by == 'link':
					elements = self.driver.find_elements_by_link_text(locator)
				elif by == 'plink':
					elements = self.driver.find_elements_by_partial_link_text(locator)
				else:
					print('Not find the element "{}"!'.format(locator))
				return elements
			except NoSuchElementException as e:
				print(traceback.print_exc())
		else:
			print('Provided a wrong locator "{}"!'.format(locator))

	# 点击页面元素
	def click(self, by, locator):
		element = self.find_element(by, locator)
		element.click()

	# 输入框输入新信息
	def type(self, by, locator, value):
		y = [x for x in value if x != '']
		if len(y) > 0:
			element = self.find_element(by, locator)
			element.clear()
			element.send_keys(value.strip())
		else:
			pass

     # 下拉菜单通过可见文本进行选择
	def select(self, by, locator, text):
		y = [x for x in text if x != '']
		if len(y) > 0:
			element = self.find_element(by, locator)
			element_element = Select(element)
			element_element.select_by_visible_text(text.strip())
		else:
			pass

	# 复选按钮勾选时我们需要首先勾掉已选选项
	def uncheck(self, by, locator, options):
		y = [x for x in options if x != '']
		if len(y) > 0:
			elements = self.find_elements(by, locator)
			for element in elements:
				element.click()
		else:
			pass

	# 选择excel表格所提供的选项进行勾选
	def check(self, by, locator, options):
		y = [x for x in options if x != '']
		if len(y) > 0:
			be_options = options.split(',')
			for option in be_options:
				element = self.find_element(by, locator.format(option.strip()))
				element.click()
		else:
			pass

	# def input(self, left_title, excel_title, by, locator, values):
	# 	y = [x for x in values if x != '']
	# 	if len(y) > 0:
	# 		if left_title == excel_title:
	# 			self.type(by, locator, values)
	# 	else:
	# 		pass

    # 根据excel表格提供标题所包含的关键字来决定进行哪种数据操作
	def update(self, title, by, values):
		y = [x for x in values if x != '']
		if len(y) > 0:
			if '_Text' in title:  # 文本框
				field = title.strip().split('_')
				locator = field[0]
				self.type(by, locator, values)
			elif '_Select' in title:  # 下拉列表
				field = title.strip().split('_')
				locator = field[0]
				self.select(by, locator, values)
			elif '_Option' in title:  # 复选按钮
				field = title.strip().split('_')
				locator = field[0]
				self.uncheck('xpath', '//input[@checked="" and contains(@id, "{}__")]'.format(locator), values)
				self.check('id', '%s__{}'%locator, values)
			else:
				print('Please indicate the data type for the title "{}" in Excel!!!'.format(title))

		else:
			pass

	# def set(self, left_title, excel_title, by, locator, text):
	# 	y = [x for x in text if x != '']
	# 	if len(y) > 0:
	# 		if left_title == excel_title:
	# 			self.select(by, locator, text)
	# 	else:
	# 		pass

	# 登录系统进行封装方便以后重用
	def login_orms(self, url, username, password):
		# driver = webdriver.Firefox(executable_path='D:\\Selenium 3.14\\geckodriver.exe')
		self.driver.delete_all_cookies()
		self.driver.get(url)
		self.driver.maximize_window()
		time.sleep(2)

		self.type('id', 'userName', username)
		self.type('id', 'password', password)
		self.click('id', 'okBtnAnchor')
		time.sleep(2)

	# 登录系统后选择Contract
	def goto_manager_page(self, url, username, password, contract, page):
		self.login_orms(url, username, password)
		time.sleep(2)
		self.click('xpath', "//option[text()='" + contract + " Contract']")  # 通过click也可以对下拉列表进行选择
		time.sleep(2)
		self.click('link', page)
		time.sleep(2)

下面是实现代码(这里没有对操作excel表格进行封装)

from Orms.BasePage import *
import xlrd

""""""
url = 'reserveamerica.com/xxxx'
account_user = 'xxx'
account_password = 'xxx'
wb = xlrd.open_workbook('D://SiteandLoopSetUp.xls')
""""""
sheet1 = wb.sheet_by_index(0)
sheet2 = wb.sheet_by_index(1)
# read provided information in Excel.
contract = sheet1.col_values(0)[1].strip()
park_name = sheet1.col_values(1)[1].strip()
search_ids = sheet1.col_values(2)[1:]
check_in_times = sheet1.col_values(3)[1:]
check_out_times = sheet1.col_values(4)[1:]

cols_num = sheet1.ncols
print('There will be "{}" fields need to update as following:'.format(cols_num))
left_titles = sheet1.row_values(0)[5:cols_num]
print(left_titles)

browser = webdriver.Firefox(executable_path='D:\\Selenium 3.14\\geckodriver.exe')
driver = BasePage(browser)
driver.goto_manager_page(url=url, username=account_user, password=account_password, contract=contract, page='Inventory Manager')

# Input park name and search
driver.type('id', 'FacilitySearchCriteria.facilityName', park_name)

driver.click('xpath', '//a[@aria-label="Search"]')
time.sleep(3)

# Click facility id in search results to facility details page
driver.click('xpath', '//tr[@name="e_Glow"]/td/a')
time.sleep(2)

# Choose Loop/Site Set-up for Facility Details drop-down list
driver.select('id', 'page_name', 'Loop/Site Set-up')
time.sleep(2)

driver.click('xpath', '//a[@tabindex="-1" and @accesskey="S"]')
time.sleep(2)

for x in range(len(search_ids)):
	try:
		driver.select('id', 'search_type', 'Site ID')
		time.sleep(2)

		driver.type('id', 'search_value', search_ids[x])

		driver.click('id', 'goAnchor')
		time.sleep(2)

		driver.click('xpath', '//tr[@name="e_Glow"]/td[2]/a')
		time.sleep(2)

		# in_time and out_time are required fields, need to handle separately.
		in_time = check_in_times[x].strip().split(' ')
		y = [x for x in in_time if x != '']
		if len(y) > 0:
			driver.type('id', 'Checkin Time', in_time[0])
			driver.select('id', 'Checkin Time_ispm', in_time[1])
		else:
			pass

		out_time = check_out_times[x].strip().split(' ')
		y = [x for x in out_time if x != '']
		if len(y) > 0:
			driver.type('id', 'Checkout Time', out_time[0])
			driver.select('id', 'Checkout Time_ispm', out_time[1])
		else:
			pass

		# update left information in excel.
		for i in range(len(left_titles)):
			title = left_titles[i]
			excel_values = sheet1.col_values(5+i)[1:]
			driver.update(title, 'id', excel_values[x])
	except Exception as e:
		raise Exception
	else:
		driver.click('xpath', '//a[@aria-label="OK"]')

以上就是我模拟手工操作进行自动填写页面表格的实现方法,虽然每次做都需要查找需要更新信息的页面元素ID的值并拷贝到excel中,但是对于几十个Contract几十种形式的site类型,加起来有上千个fields需要单独处理,这样做就显得简单很多。

当然肯定还有不完善的地方,比如都用的强制等待而没有用隐形等待,也一定有更好的实现方式,欢迎各位指正~~~

你可能感兴趣的:(自动填写表单程序)