python实现清华大学联网助手(二)——正则表达式re/网页跳转/cookiejar

清华大学算法训练营 —— 栈程序 栈程序 时间限制:2s,空间256MB 问题描述 实现一个栈,完成以下功能: 入栈 出栈 查询栈中位置Y是谁 一开始栈为空,栈中的位置从1开始(即栈底位置为1)。 输入 第一行一个整数n,表示操作个数(1 <= n <= 100000) 接下来n行,每行第一个数字表示操作(见描述): 若为数字1,则接下来有一串字符串X,表示将X压入栈中。 若为数字2,表... 阅读详情

本篇是第二篇。

本篇要实现python实现清华大学联网助手(一)——urllib/hashlib/getopt/time/codecs的使用中提到的大部分功能。主要新增的功能是:查询流量、帐户余额、当前用户组等基本信息;查询本账号当前在线IP信息;查询每日流量使用明细,并生成直方图。而且需要访问的url不在是之前登录校园网的url。

如果你是希望找到以下问题的答案,请移步至python实现清华大学联网助手(一)——urllib/hashlib/getopt/time/codecs的使用。

1 如何利用hashlib处理密码;

2 如何实现带账号密码登录的网页request和urlopen;

3 如何实现带参数输入的自定义命令;

4 如何实现当前日期和时间的获取;

5 if __name__ == '__main__'的作用。


总结以下需要实现上述功能所遇到的问题:

1 文件的打开和读写和关闭;

2 cookiejar实现网页登录和cookie状态的保存;

3 网页登录跳转;

4 正则表达式re模块的使用方法和注意事项。


1 文件的打开和读写和关闭:

a) 获取当前的目录的绝对路径

os模块带有一个获取当前执行脚本(argv[0])的绝对路径的函数方法os.path.abspath(os.path.dirname(sys.argv[0]))。它通过os.path.dirname(sys.argv[0])获取当前执行脚本的名字并通过abspath找到它的绝对地址。

现在我们已经有了当前目录的绝对地址了。我们只需要将它与相对地址结合,就得到了我们要打开的文件地址。用到了os.path.join(base_path, relative_path)。

def create_path(relative_path):
 	base_path = os.path.abspath(os.path.dirname(sys.argv[0]))
 	return os.path.join(base_path, relative_path)

b) 文件的打开和读写和关闭

各个语言对文件打开/读写/关闭的语法都大同小异。

具体的语法请见Python的文件IO相关操作说明,我这里主要用到了open(),write_inline(),write(),close()。

def save_query(contents):
	relative_path = 'USER_DETAIL_INFOMATION.LOG'
	file_handler = open(create_path(relative_path), 'w')
	write_inline(file_handler, info_header)
	file_handler.write('\t\t\t\tDatetime: ' + time.strftime('%Y-%m-%d %H:%M:%S') + '\r\n' + '-' * 89 + '\r\n')
	write_inline(file_handler, contents)
	file_handler.write('\r\n')
	file_handler.close()

我给存储查询结果的文件命名为USER_DETAIL_INFOMATION.LOG,打开通过上面的方法得到的文件绝对地址,写入数据后关闭文件。记住一定要关闭文件,否则会占用系统活跃文件inode列表,减少了系统可操作的文件数。具体写入的内容就是自己决定了。


2 cookiejar实现网页登录和cookie状态的保存:

需要载入http.cookiejar模块。

在python实现清华大学联网助手(一)——urllib/hashlib/getopt/time/codecs的使用这篇文章中,由于我们只需要登录校园网一次就可以完成联网操作。因此不必要在登陆状态下进行任何其它页面内的作业。但现在我们必须维持当前的登录状态,并且在各个跳转页面中抓取所需信息。因此我们就需要cookiejar,而不能仅单纯地使用urlopen()。

先讲一讲cookiejar的工作机制:

cookie是由服务器端生成并发送给User-Agent(比如浏览器),浏览器将这个键值对(username, password)保存到某个文本文件中,下次继续登录该网址基址下的各个页面时,都附带这个cookie状态,保证页面能够正常访问。cookiejar的实例就是模拟浏览器保存用户名和密码这个键值对的容器,我们将这个cookiejar实例作为参数传递给opener,那么我们只需一次登录就能记住这个cookie状态,下次请求页面时自动附带cookie状态。

应注意,python3并没有urllib2,因此代码可能与python2有所不同。

def create_opener():
	cookie = http.cookiejar.CookieJar()
	cookie_proc = urllib.request.HTTPCookieProcessor(cookie)
	return urllib.request.build_opener(cookie_proc)

def response_login(login_data):
	request_url = urllib.request.Request(query_login_url, login_data.encode())
	response_url = urllib.request.urlopen(request_url)
	return response_url.read().decode()

def query_login(username, password):
	hashcd_md5 = hashlib.md5()
	hashcd_md5.update(password.encode())
	tr_password = hashcd_md5.hexdigest()
	login_data = 'user_login_name=' + username + '&user_password=' + tr_password + '&action=login'
	urllib.request.install_opener(create_opener())
	answer = response_login(login_data)
	if answer == 'ok':
		return True
	else:
		return False

def query_logout():
	logout_data = 'action=logout'
	request_url = urllib.request.Request(query_logout_url, logout_data.encode())
	response_url = urllib.request.urlopen(request_url)
	print ('Your flux details and other infomations are saved in USER_DETAIL_INFOMATION.LOG under the SAME directory')
基本步骤:

a) cookie = http.cookiejar.CookieJar();

b) cookie_proc = urllib.request.HTTPCookieProcessor(cookie),生成一个cookiejar实例;

c) bopener = urllib.request.build_opener(cookie_proc),创建一个opener;

d) urllib.request.install_opener(bopener),装载该opener;

e) 像普通访问需要登录url一样,request和urlopen,这是第一次登录,cookie信息会被记录和保存;

f) 所有其他子页面都用urlopen即可。


3 网页登录跳转:

网页的响应正文可能会提供跳转的url。普通的header跳转urllib会自动完成,而js跳转则需要你通过一些手段去获取真实的跳转网址。由于我们所需访问的网页并不存在这个问题,这里不再赘述。感兴趣可以google。


4 正则表达式re模块的使用方法和注意事项:

抓取了页面的所有信息,我们需要解析网页,提取对我们有用的信息。这也一度让我非常头疼。有很多可以用来解析网页内容的优秀模块,比如BeautifulSoup。但我必须考虑没有安装这个包的用户,因此最后决定用正则表达式re模块完成所需信息的提取。

首先需要学习正则表达式。看起来十分复杂,但会用到语法可能并不多,推荐这个教程:正则表达式30分钟入门教程。尤其应注意正则表达式的贪婪和懒惰特性。

然后是re模块的几个常用函数。re.sub(),re.search(),re.findall()。

a) re.sub():

sub是substitute的缩写,表示代替。接受3个参数,一个正则表达式,一个代替字符串,一个待处理的字符串内容。比如done = re.sub('<[^>]+>|&nbsp;|[\n\t]+|-->',' ',raw)表示将raw字符串中符合这个'<[^>]+>|&nbsp;|[\n\t]+|-->'正则表达式的部分都用‘’代替(这意味着删除这个符合正则表达式的部分),同时返回处理后的字符串。如果学过上面正则表达式教程的话,应该明白'<[^>]+>|&nbsp;|[\n\t]+|-->'是表示删除raw中所有的标签、空格、回车、制表符和‘-->’形式的字符串。

b) re.search():

search()需要2参数,一个正则表达式和待处理字符串。返回匹配对象。通过group()方法获得字符串。group(n)表示返回匹配的第n个字符串,group()表示返回第一个匹配字符串。而groups()方法比较复杂,是返回所有成功匹配的字符串的一个组合。

match = re.search('用户名.*?(元) ', done)
done = match.group()
c) re.findall():

re.findall()是获取字符串中所有匹配的字符串。

d) re.compile():

这是将一个正则表达式编译成一个正则表达式对象,可以多次使用,提高效率。


BONUS:最后提示一个让脚本暂停一段时间继续执行的函数,time.sleep(gap),gap为秒数。这样可以防止过于频繁的请求动作。


提供实现代码,一个分为3个.py文件:

pytunet_query.py

import sys, time, os
import urllib.request, hashlib, http.cookiejar
import codecs, re

query_login_url  = 'https://usereg.tsinghua.edu.cn/do.php'
user_info_url = 'https://usereg.tsinghua.edu.cn/user_info.php'
online_state_url = 'https://usereg.tsinghua.edu.cn/online_user_ipv4.php'
query_logout_url = 'https://usereg.tsinghua.edu.cn/do.php'

info_header = [ '#' * 89,
				'#\t\t\t\tUser Flux Detail Infomation\t\t\t\t#',
				'#' * 89]

#########################################################
#					File I/O Modules					#
#########################################################

def create_path():
 	relative_path = 'USER_DETAIL_INFOMATION.LOG'
 	base_path = os.path.abspath(os.path.dirname(sys.argv[0]))
 	return os.path.join(base_path, relative_path)

def write_inline(file_handler, contents):
	for line in contents:
		file_handler.write(line + '\r\n')

def save_query(contents):
	file_handler = open(create_path(), 'w')
	write_inline(file_handler, info_header)
	file_handler.write('\t\t\t\tDatetime: ' + time.strftime('%Y-%m-%d %H:%M:%S') + '\r\n' + '-' * 89 + '\r\n')
	write_inline(file_handler, contents)
	file_handler.write('\r\n')
	file_handler.close()

#########################################################
#					Connection Modules					#
#########################################################

def create_opener():
	cookie = http.cookiejar.CookieJar()
	cookie_proc = urllib.request.HTTPCookieProcessor(cookie)
	return urllib.request.build_opener(cookie_proc)

def response_login(login_data):
	request_url = urllib.request.Request(query_login_url, login_data.encode())
	response_url = urllib.request.urlopen(request_url)
	return response_url.read().decode()

#########################################################
#				Main Login/Logout Modules				#
#########################################################

def query_login(username, password):
	hashcd_md5 = hashlib.md5()
	hashcd_md5.update(password.encode())
	tr_password = hashcd_md5.hexdigest()
	login_data = 'user_login_name=' + username + '&user_password=' + tr_password + '&action=login'
	urllib.request.install_opener(create_opener())
	answer = response_login(login_data)
	if answer == 'ok':
		return True
	else:
		return False

def query_logout():
	logout_data = 'action=logout'
	request_url = urllib.request.Request(query_logout_url, logout_data.encode())
	response_url = urllib.request.urlopen(request_url)
	print ('Your flux details and other infomations are saved in USER_DETAIL_INFOMATION.LOG under the SAME directory')

#########################################################
#				Data Post-Process Modules				#
#########################################################

def post_process(info):
	end_time = time.strftime('%Y-%m-%d')
	start_time = end_time[:8:] + '01'
	flux_detail_url = 'https://usereg.tsinghua.edu.cn/user_detail_list.php?action=balance2&user_login_name=&user_real_name=&desc=&order=&start_time=' + start_time + '&end_time=' + end_time + '&user_ip=&user_mac=&nas_ip=&nas_port=&is_ipv6=0&page=1&offset=200'	

	response_usr = urllib.request.urlopen(user_info_url)
	response_state = urllib.request.urlopen(online_state_url)
	response_details = urllib.request.urlopen(flux_detail_url)

	info = flux_account_query(info, response_usr)
	info = online_state_query(info, response_state)
	info = flux_detail_query(info, response_details)
	
	return info

#########################################################
#				Integrated Query Modules				#
#########################################################

flux_account_keys = ('用户名', '用户组', '姓名', '证件号', '当前计费组', '使用时长(IPV4)', '使用流量(IPV4)',
					 '使用时长(IPV6)', '使用流量(IPV6)', '帐户余额')
online_state_keys = ()
flux_detail_keys  = ()

#Auxiliary Function
def turn_key(key):
	if key[-5:-1] == 'byte':
		flux, unit = key.split('(')
		flux = float(flux) / 1024 / 1024
		new_key = '-->' + str(int(flux)) + '(MB)'
		key += new_key
	return key


def get_days(year, month):
	month_length = (31,28,31,30,31,30,31,31,30,31,30,31)
	month_length_leap = (31,29,31,30,31,30,31,31,30,31,30,31)
	if year % 400 == 0 or year % 100 != 0 and year % 4 == 0:
		return month_length_leap[month-1]
	else:
		return month_length[month-1]

def solve_flux(flux):
	unit = flux[-1]
	val = float(flux[:len(flux)-1:])

	if unit == 'B':
		val /= 1024 * 1024
	elif unit == 'K':
		val /= 1024
	elif unit == 'G':
		val *= 1024

	return int(val)

def trans_content(response):
	raw = response.read().decode('gb2312')
	raw = re.sub('<[^>]+>| |[\n\t]+|-->',' ',raw)
	raw = re.sub(' +', ' ', raw)
	return raw

def push_front(figure, line):
	tf = []
	tf.append(line)
	return tf + figure

def display_fluxAccount_onlineState(info):
	print()
	for line in info:
		if line[0] != '-':
			print(line)
		else:
			print()

def display_flux_detail(fluxin, year, month, day):
	maxflux = 0
	divide = 10
	figure = []
	for flux in fluxin:
		if flux > maxflux:
			maxflux = flux

	top = str(int(maxflux)) + 'MB|'
	length = len(top)
	mid = str(int(maxflux / 2)) + 'MB|'
	mid = ' ' * (length - len(mid)) + mid
	bottom = '0MB|'
	bottom = ' ' * (length - len(bottom)) + bottom
	unit = maxflux / divide

	for i in range(day):
		fluxin[i] = int(fluxin[i] / unit)

	for i in range(divide):
		line = ''
		if i == divide - 1:
			line = top
		elif i == int((divide - 1) / 2):
			line = mid
		elif i == 0:
			line = bottom
		else:
			line = ' ' * (length - 1) + '|'
		for j in range(day):
			if fluxin[j] > 0:
				line += '**'
				fluxin[j] -= 1
			else:
				line += '  '

		figure = push_front(figure, line)

	figure = push_front(figure, '**每日流量使用统计列表**')
	figure.append(' ' * length + '--' * day)
	date_front = str(year) + '-' + str(month) +'-' + '1'
	date_rear  = str(year) + '-' + str(month) +'-' + str(day)
	date_mid   = str(year) + '-' + str(month) +'-' + '15'
	figure.append(' %s\t\t\t%s\t\t\t%s' %(date_front, date_mid, date_rear))

	for line in figure:
		print(line)

	print()

#Integrated Query
def flux_account_query(info, response):
	info.append('**用户基本信息**')
	done = trans_content(response)
	match = re.search('用户名.*?(元) ', done)
	done = match.group()
	tlist = done.split(' ')
	line = ''

	for key in tlist:
		if line != '':
			key = turn_key(key)
			line = line + '\t: ' + key
			info.append(line)
			line = ''
		elif key in flux_account_keys:
			line = key

	info.append('-' * 89)
	return info

def online_state_query(info, response):
	info.append('**用户在线状态**')
	
	done = trans_content(response)
	match = re.search('\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}.*\d{2}:\d{2}', done)

	if match == None:
		info.append('当前没有任何IP在线')
	else:
		info.append('在线IP地址\t登陆日期\t登陆时间')
		done = match.group()
		tlist = done.split(' ')
		line = ''
		count = 0

		for key in tlist:
			if count == 0:
				if re.search('\d{1,3}\.\d{1,3}\.\d{1,3}.\d{1,3}', key) != None:
					line = key
					count += 1
			elif count == 1:
				if re.search('\d{4}-\d{2}-\d{2}', key) != None:
					line += '\t' + key
					count += 1
			elif count == 2:
				if re.search('\d{2}:\d{2}:\d{2}', key) != None:
					line += '\t' + key
					info.append(line)
					line = ''
					count = 0

	info.append('-' * 89)
	display_fluxAccount_onlineState(info);
	return info

def flux_detail_query(info, response):
	info.append('**每日流量使用统计列表**')
	info.append('登出日期\t入流量\t出流量')
	done = trans_content(response)
	year, month = time.strftime('%Y %m').split(' ')
	days = get_days(int(year), int(month))
	tlist = done.split(' ')

	fluxin_perday = [0 for i in range(days)]
	fluxout_perday = [0 for i in range(days)]
	offline_date = True
	count = 0

	for key in tlist:
		if re.search('\d{4}-\d{2}-\d{2}', key) and offline_date:
			offline_date = False
		elif re.search('\d{4}-\d{2}-\d{2}', key) and not offline_date:
			offline_date = True
			year, month, day = key.split('-')
			iday = int(day)
		elif re.search('\d+[.]\d*[BKMG]', key) and count == 0:
			fluxin_perday[iday-1] += solve_flux(key)
			count += 1
		elif re.search('\d+[.]\d*[BKMG]', key) and count == 1:
			fluxout_perday[iday-1] += solve_flux(key)
			count += 1
		elif re.search('\d+[.]\d*[BKMG]', key) and count == 2:
			count = 0
	
	for i in range(days):
		if i + 1 < 10:
			d = '0' + str(i + 1)
		else:
			d = str(i + 1)
		info.append('%s\t%s\t%s' %(time.strftime('%Y-%m-') + d, str(fluxin_perday[i]) + 'MB', str(fluxout_perday[i]) + 'MB'))

	display_flux_detail(fluxin_perday, int(year), int(month), days)
	return info

#########################################################
#						Main Part						#
#########################################################

def tunet_query(username, password):
	print('FETCHING DATA FROM http://usereg.tsinghua.edu.cn, PLEASE WAIT A MOMENT...')
	is_login = query_login(username, password)
	if is_login:
		info = []
		info = post_process(info)
		save_query(info)
		query_logout()
	else:
		print ('CAN\'T CAPTURE YOUR FLUX DATA, PLEASE TRY AGAIN LATER')

def pytunet_query():
	username = 'hhy14'
	password = '123456'
	tunet_query(username, password)

if __name__ == '__main__':
	pytunet_query()


pytunet_connect.py:

import time
import urllib.request, hashlib
import codecs

login_url  = 'http://net.tsinghua.edu.cn/cgi-bin/do_login'
logout_url = 'http://net.tsinghua.edu.cn/cgi-bin/do_logout'
check_url  = 'http://net.tsinghua.edu.cn/cgi-bin/do_login'
query_url  = 'https://usereg.tsinghua.edu.cn/login.php'

times_cnt = {1: 'FIRST', 2: 'SECOND', 3: 'THIRD', 4: 'FORTH', 5: 'FIFTH'}
ret_type  = {'logout_ok'       : 'LOGOUT SUCCESS',
			'not_online_error' : 'NOT ONLINE',
			'ip_exist_error'   : 'IP ALREADY EXISTS',
			'user_tab_error'   : 'THE CERTIFICATION PROGRAM WAS NOT STARTED',
			'username_error'   : 'WRONG USERNAME',
			'user_group_error' : 'ACCOUNT INFOMATION INCORRECT',
			'password_error'   : 'WRONG PASSWORD',
			'status_error'     : 'ACCOUNT OVERDUE, PLEASE RECHARGE',
			'available_error'  : 'ACCOUNT HAS BEEN SUSPENDED',
			'delete_error'     : 'ACCOUNT HAS BEEN DELETED',
			'usernum_error'    : 'USERS NUMBER LIMITED',
			'online_num_error' : 'USERS NUMBER LIMITED',
			'mode_error'       : 'DISABLE WEB REGISTRY',
			'time_policy_error': 'CURRENT TIME IS NOT ALLOWED TO CONNECT',
			'flux_error'       : 'FLUX OVER',
			'ip_error'         : 'IP NOT VALID',
			'mac_error'        : 'MAC NOT VALID',
			'sync_error'       : 'YOUR INFOMATION HAS BEEN MODIFIED, PLEASE TRY AGAIN AFTER 2 MINUTES',
			'ip_alloc'         : 'THE IP HAS BEEN ASSIGNED TO OTHER USER'
			}

version  = '1.1'
sleep_time = 8

def trans_content(response):
	content = response.read().decode()
	ret = ''
	for ch in content:
		if ch.isalpha() or ch == '_':
			ret += ch
	return ret

def tunet_login(username, password):
	hashcd_md5 = hashlib.md5()
	hashcd_md5.update(password.encode())
	tr_password = hashcd_md5.hexdigest()
	login_data = 'username=' + username + '&password=' + tr_password + '&drop=0&type=1&n=100'
	login_data = login_data.encode()
	request_url = urllib.request.Request(login_url, login_data)
	response_url = urllib.request.urlopen(request_url)
	ret = trans_content(response_url)
	print (ret_type.get(ret, 'CONNECTED'))
	return ret

def tunet_logout():
	response_url = urllib.request.urlopen(logout_url)
	ret = trans_content(response_url)
	print (ret_type.get(ret, 'CONNECTED'))
	return ret

def tunet_check():
	check_data = 'action=check_online'
	check_data = check_data.encode()
	request_url = urllib.request.Request(check_url, check_data)
	response_url = urllib.request.urlopen(request_url)
	ret = trans_content(response_url)
	if ret == '':
		print ('NOT ONLINE')
	else:
		print (ret_type.get(ret, 'CONNECTED'))
	return ret

def tunet_help():
	print ('-h, --help   : show all options of Tsinghua University Internet Connector')
	print ('-v, --version: show version of Tsinghua University Internet Connector')
	print ('-u           : input your username after \'-u\'')
	print ('-p           : input your password after \'-p\'')
	print ('-a           : enter username and password later, you can login other campus network account')
	print ('-i, --login  : login operation')
	print ('-o, --logout : logout operation')
	print ('-c, --check  : check the internet')
	print ('-q, --query  : query basic infomation, online state and flux usage details')

def tunet_version():
	print ('Tsinghua University Internet Connector ', version)

def tunet_others():
	print ('UNKNOWN OPTIONS')
	print ('WHICH OPTION DO YOU WANT?')
	tunet_help()
	print ('IF ANY ERROR, PLEASE CONTACT im@huhaoyu.com.')

def tunet_connect(username, password):

	ret = 'ip_exist_error'
	for count in range(5):
		print ('%s attempts to connect...' % times_cnt.get(count + 1))
		if ret != tunet_login(username, password):
			break
		if count == 4:
			print ('please try to reconnect after 1 minute')
			break
		print ('try to reconnect after %s seconds' %sleep_time)
		time.sleep(sleep_time)
		print ()

pytunet.py:

#########################################################
#						Welcome							#
#	Tsinghua University Internet Connector in Python	#
#					 Version: v1.1 						#
#					Date: 2015/04/03					#
#			By: Haoyu hu	Email: im@huhaoyu.com		#
#			Address: Tsinghua University				#
#########################################################

import pytunet_connect
import pytunet_query
import sys, getopt, getpass

def pytunet():

	username = 'hhy14'
	password = '123456'
	try:
		options, args = getopt.getopt(sys.argv[1:], 'achiop:qu:v', ['help', 'login', 'logout', 'check', 'version', 'query'])
	except getopt.GetoptError:
		pytunet_connect.tunet_others()
		sys.exit(1)

	want_login = False
	want_query = False
	flag = False

	name, value = None, None

	for name, value in options:
		if name in ('-h', '--help'):
			pytunet_connect.tunet_help()
			sys.exit(0)
		elif name in ('-v', '--version'):
			pytunet_connect.tunet_version()
			sys.exit(0)
		elif name == '-a':
			flag = True
		elif name == '-u':
			username = value
		elif name == '-p':
			password = value
		elif name in ('-i', '--login'):
			want_login = True
		elif name in ('-o', '--logout'):
			pytunet_connect.tunet_logout()
			sys.exit(0)
		elif name in ('-c', '--check'):
			pytunet_connect.tunet_check()
			sys.exit(0)
		elif name in ('-q', '--query'):
			want_query = True

	if flag:
		username = input('username: ')
		password = getpass.getpass('password: ')
		print (password)

	if want_query:
		pytunet_query.tunet_query(username, password)

	if want_login:
		pytunet_connect.tunet_connect(username, password)

	if not want_query and not want_login:
		print ('WARNING: YOU JUST DIDN\'T DO ANYTHING! IF YOU WANT TO CONNECT TO THE CAMPUS NETWORK, THE COMMAND MUST INCLUDE -i OR --login')
		print()
		pytunet_connect.tunet_help()

if __name__ == '__main__':
	pytunet()

代码或分析有误请批评指正,谢谢!


iTunet清华校园网络客户端 一款清华大学新的校园网络客户端登陆软件,支持断线重连,支持windows7系统。 立即下载

相关推荐

神经元细胞结构刨析(持续更新)

神经细胞的学习笔记

weixin_46596227的博客 2220

python之正则表达式match()方法

>>>import re >>>m=re.match('^\w+','foo') >>> if m is not None: print 'this is foo' this is foo >>>

mengtianwxs的专栏 752

车载机器人终极解决方案:从功能叠加到生态融合的颠覆性变革

本文提出一种融合智能汽车与家居技术的车载机器人架构。其创新点包括:1)基于多模态传感器的拟人化硬件设计,实现声源定位误差<5°、体温检测精度±0.3℃;2)跨模态情感计算引擎,综合面部表情、心率等数据构建三维情绪模型;3)协议自适应中间件,支持小米、华为等多品牌智能家居设备即插即用;4)环境自适应舵机控制,-30℃环境下扭矩保持率达92.5%。测试数据显示,该方案使交互步骤减少60%,用户满意度提升58%,日均使用时长增加2.3倍,为"人-车-家"生态融合提供了可行技术路径。

qq_42671193的博客 1123

python从入门到精通(八): python正则表达式

d{3,4} 既可以匹配3个数字也可以匹配4个数字,不过当有4个数字的时候,优先匹配的是4个数字,这是因为正则表达式默认是贪婪模式,即尽可能的匹配更多字符,而要使用非贪婪模式,我们要在表达式后面加上?值得注意的是: .字符只有一个不能匹配的字符,也就是换行符(\n),不过要让.字符与换行符匹配也是可以的,以后会讨论。例如:如果要取出喜欢两个字,要求喜欢的前面没有我,后面没有你,这个时候就要这么写:(?例如:如果要取出喜欢两个字,要求喜欢的前面有我,后面有你,这个时候就要这么写:(?

HACKONE的博客 1041

从Blender舞步到夜空画卷:基于Pix飞控的无人机编队灯光秀全链路开发实践

本文详细介绍了基于Pixhawk飞控的无人机编队灯光秀全链路开发实践。从Blender三维动画设计、QGroundControl地面站二次开发与MAVLink通信桥接,到PX4飞控的OFFBOARD模式路径控制与LED灯光驱动实现,最后通过Gazebo仿真验证并完成真机组装与首飞。文章为无人机爱好者提供了一套完整的、从创意设计到夜空执行的开源解决方案,重点阐述了多机同步与灯光控制的核心技术挑战与应对策略。

zeta9的博客 585

(精读)揭示多元时间序列的高阶组织

时间序列分析已经被证明是刻画生物学、神经科学和经济学中的一些现象以及理解它们的一些潜在动力学特征的有力方法。尽管针对多元时间序列的分析已经提出了很多方法,但大多数方法都忽略了非成对相互作用对涌现动力学的影响。在这里,我们提出了一个新的框架来刻画多元时间序列中高阶依赖关系的时间演化。利用网络分析和拓扑学,我们表明,与传统的基于成对统计的工具不同,我们的框架鲁棒地区分了耦合混沌映射的各种时空状态,包括混沌动力学阶段和各种类型的同步。

weixin_53406075的博客 2412

pexpect模块

Pexpect是一个用来启动子程序并对其进行自动控制的Python模块,它可以用来和像ssh,ftp,passwd,telnet等命令行程序进行自动交互。 下载安装: http://sourceforge.net/projects/pexpect/ 概念理解: Expect 程序主要用于人机对话的模拟,就是那种系统提问,人来回答 yes/no ,或者账号登录输入用户名和密码等等的情况。 ...

weixin_34221332的博客 751

1、Ovirt 开源虚拟化平台安装

Ovirt虚拟化Node和Engine安装

大鱼 6266

Python进阶

# Python进阶*argv 和 **kwargs  与函数有关,但是在函数调用和函数声明时行为有所不同。(这个星号与指针毫无关系!)   一般来说,单个星号表示有元组(或是列表)出现,而两个星号则代表字典出现。 整理知识,学习笔记 * 撰写发布技术文稿(代码支持) 撰写发布学术论文(LaTeX 公式支持) 函数调用  调用函数时,表达式会在计算一个带单星号的元组

wubingheng的博客 529

华为OD机试双机位C卷:打印机队列 (C++/Py/C/Java/Js/Go)

华为OD机试双机位C卷 打印机队列,提供C语言、Java、C++、Python、Go、JavaScript源码实现,并提供完整思路讲解。华为OD机试 - 打印机队列。

qq_45776114的博客 1793

第二节:Vben Admin 最新 v5.0 (vben5) + Python Flask 快速入门 - Python Flask 后端开发详解(附源码)

大家好,我是cuiwin!本节内容,我们从零开始开发基于Python(Flask)的后端项目,对接Vue Vben Admin(vben5)。登录mysql数据库执行: 创建数据库。

cuiwin的专栏 2264

转:Python正则表达式操作指南

Python正则表达式操作指南 出自Ubuntu中文 原文出处:http://www.amk.ca/python/howto/regex/ 原文作者:A.M. Kuchling (amk@amk.ca) 授权许可:创作共用协议 翻译人员:FireHare 校对人员:Leal 适用版本:Python 1.5 及后续版本 摘要 本文是通过Python的 re...

weixin_30615767的博客 451

EMB电子机械制动执行器五大核心部件选型解析

本文介绍了EMB电子机械制动执行器五大核心部件的选型方案:采用无刷直流电机作为驱动源,兼具高扭矩和快速响应特性;选用滚珠丝杠传动机构,实现高效旋转-直线转换;行星齿轮减速器满足紧凑空间内的增扭需求;QT450-QT550材质的钳体确保刚度要求;应变片式压力传感器实现夹紧力精确测量。各部件选型综合考虑了性能、可靠性和空间限制,为EMB系统设计提供了完整解决方案。

m0_59012156的博客 1733

PYTHON | 高级教程

教程地址:Python 高级教程 面向对象技术简介 类(Class): 用来描述具有相同的属性和方法的对象的集合。它定义了该集合中每个对象所共有的属性和方法。对象是类的实例。 类变量:类变量在整个实例化的对象中是公用的。类变量定义在类中且在函数体之外。类变量通常不作为实例变量使用。 数据成员:类变量或者实例变量, 用于处理类及其实例对象的相关的数据。 方法重写:如果从父类继承的方法不能满足子类...

⊳ideal world⊲~ヽ(゚︺゚)Hi 1967

STM32F407中文手册

STM32f407中文手册 本参考手册面向应用开发人员,提供有关使用 STM32F405xx/07xx、STM32F415xx/17xx、 STM32F42xxx 和 STM32F43xxx 微控制器存储器与外设的完整信息。STM32F405xx/07xx、STM32F415xx/17xx、STM32F42xxx 和 STM32F43xxx 构成一个微 控制器系列,各产品具有不同的存储器大小、封装和外设。有关订购信息以及器件的机械与电气特性,请参见数据手册。有关 ARM Cortex™-M4F 内核的信息,请参见《Cortex™-M4F 技术参考手册》。

C# WinForm 基于DirectShow.dll编写的程序,可边预览边保存视频,音频和图片

基于微软的DirectShow.dll的二次开发1.自动识别连接的摄像头跟麦克风且可以对其进行选择(默认选中第一个)2.可录制wmv和avi两种格式的视频并且都带有音频,avi可以录制的分辨率和帧数进行选择,wmv默认进行了淸晰度优化如不喜欢可去除代码中有相关提示3.可在预览点开之后进行拍照,也可边录制视频边拍照4.添加了视频和音频的压缩功能(酌情使用)这次二次开发发现C#对DirectShow的相关信息太少,这次做完也不敢藏私共享出来,还望大家指正

0基础学python-18:古希腊掌管匹配机制的模块——re正则表达式

正则表达式,re模块

纸上得来终觉浅 1054

大中型超市收银系统(可直接运行)

光步前台收银系统系统功能:商品销售、商品退货、挂单、收银员权限、会员销售、单品取消、整单取消、商品查询、脱机销售、脱机数据上传,基本资料下载,开钱箱、小票打印、收款结算,支持多币种付款方式(现金、储值卡、礼券、微信等),支持多种促销。运行环境:.net 4.0登陆信息用户名:1001 密码:123456内置商品信息,商品编码可输入00001000 - 00010000,测试效果相关功能键F5 结算 F9挂单 F11商品查询 F8退货 Insert单品取消 Del整单取消 F12开钱箱F2 会员 Ctrl+Z退出系统 Home 锁屏 相关源码待公开

Python之网络爬虫完全教程

[Python]网络爬虫(一):抓取网页的含义和URL基本构成 一、网络爬虫的定义 网络爬虫,即Web Spider,是一个很形象的名字。 把互联网比喻成一个蜘蛛网,那么Spider就是在网上爬来爬去的蜘蛛。 网络蜘蛛是通过网页的链接地址来寻找网页的。 从网站某一个页面(通常是首页)开始,读取网页的内容,找到在网页中的其它链接地址, 然后通过这些链接地址寻找下一

roler_的专栏 2万+

假人有限元模型

假人模型,车辆碰撞假人有限元模型,适合做乘员安全的研究者利用

Python 学习入门(13)—— 正则表达式

Python正则表达式指南

阳光岛主 1万+

python常用的国内源地址(建议使用清华源)

python加速换源安装

sdcspn的博客 3408

bat 自动输入密码_清华校园网自动连接方案:Python+Selenium

文章目录- 安装Python- 安装Firefox及geckodriver- 使用Selenium连接清华网- Windows定时运行VB脚本本人在去年2月曾分享过清华校园网自动连网方案(https://mp.weixin.qq.com/s/XfDF8r7gPs0OH6n3hUftTg)。但是自从校园网改版成auth4登录后,我们不得不面临一个尴尬的事实,那就是原来的Python+req...

weixin_39524147的博客 1417

Python爬虫实战三之计算大学本学期绩点

大家好,本次为大家带来的项目是计算大学本学期绩点。首先说明的是,博主来自山东大学,有属于个人的学生成绩管理系统,需要学号密码才可以登录,不过可能广大读者没有这个学号密码,不能实际进行操作,所以最主要的还是获取它的原理。最主要的是了解cookie的相关操作。 本篇目标 1.模拟登录学生成绩管理系统 2.抓取本学期成绩界面 3.计算打印本学期成绩 1.URL的获取 恩,博主来自山东大学~

shengxiaweizhi的专栏 1165

Python 使用清华大学镜像源

官方地址 首先,如果只是临时下载一个包 那么可以使用 pip install -i https://pypi.tuna.tsinghua.edu.cn/simple 要下的包名 如果是永久修改镜像源 pip install pip -U pip config set global.index-url https://pypi.tuna.tsinghua.edu.cn/simple 如果网络不好...

liuYinXin的博客 13万+

【Nodejs】登录鉴权-Cookie

在互联网应用中,一般网站(如掘金)会有两种模式,游客模式和登录模式。游客模式下,可以正常浏览网站上面的文章,一旦想要点赞/收藏/分享文章,就需要登录或者注册账号。当用户登录成功后,服务器会给该用户使用的浏览器颁发一个令牌(token),这个令牌用来表明你的身份,每次浏览器发送请求时会带上这个令牌,就可以使用游客模式下无法使用的功能。

DomCode 870

Python 正则式学习笔记

1.  Python正则式的基本用法 1.1基本规则 1.2重复 1.2.1最小匹配与精确匹配 1.3前向界定与后向界定 1.4组的基本知识 2.  re模块的基本函数 2.1使用compile加速 2.2 match和search 2.3 finditer 2.4 字符串的修改与替换 3.  更深入的了解re的组与对象 3.1编译后的Pattern对象 3.2

whycadi的专栏 6万+

linux系统ip重启命令,第五章 Linux操作系统关机、重启、注销及其查看ip命令

一、更新系统时间与网络时间同步1. 安装ntpdate工具# yum -y install ntp ntpdate2. 设置系统时间与网络时间同步# ntpdate cn.pool.ntp.org3. 将系统时间写入硬件时间# hwclock --systohc4.强制系统时间写入CMOS中防止重启失效#hwclock -w二、关机重启以及注销命令1.关机[[emailprotected]...

weixin_39715460的博客 318

python页面跳转代码_Python flask框架实现浏览器点击自定义跳转页面

代码如下_init_.pyfrom flask import Flask, request, url_for, redirect, render_templateapp = Flask(__name__)@app.route('/')def index():return render_template('index.html')@app.route('/cool_form', methods=['...

weixin_39737051的博客 935

正则表达式re.compile()的使用

re 模块提供了不少有用的函数,用以匹配字符串,比如: compile 函数 match 函数 search 函数 findall 函数 finditer 函数 split 函数 sub 函数 subn 函数 re 模块的一般使用步骤如下: 使用 compile 函数将正则表达式的字符串形式编译为一个 Pattern 对象 通过 Pattern 对象提供的一系列方法对文本进行匹...

精灵码农 16万+
上一篇: python实现清华大学联网助手(一)——urllib/hashlib/getopt/time/codecs的使用
下一篇: python实现清华大学联网助手(三)——linux下带参数的自定义命令/import机制
coderhuhy
博客等级 码龄12年 24粉丝 40原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值