十四、XML
一、 样例
1:获取QQ状态
1 import requests 2 from xml.etree import ElementTree as ET 3 4 #解析XML格式内容 5 r = requests.get('http://www.webxml.com.cn//webservices/qqOnlineWebService.asmx/qqCheckOnline?qqCode=893029290') 6 result = r.text 7 node = ET.XML(result) #node 是element 对象 8 9 #获取内容 10 if node.text == 'Y': 11 print('在线') 12 else: 13 print('离线')
2: 火车时刻表
1 import urllib 2 import requests 3 from xml.etree import ElementTree as ET 4 5 # 使用内置模块urllib发送HTTP请求,或者XML格式内容 6 """ 7 f = urllib.request.urlopen('http://www.webxml.com.cn/WebServices/TrainTimeWebService.asmx/getDetailInfoByTrainCode?TrainCode=G666&UserID=') 8 result = f.read().decode('utf-8') 9 """ 10 11 # 使用第三方模块requests发送HTTP请求,或者XML格式内容 12 r = requests.get('http://www.webxml.com.cn/WebServices/TrainTimeWebService.asmx/getDetailInfoByTrainCode?TrainCode=G666&UserID=') 13 result = r.text 14 15 # 解析XML格式内容 16 root = ET.XML(result) 17 18 for node in root.iter('TrainDetailInfo'): 19 print(node.tag, node.attrib) 20 print(node.find('TrainStation').text, node.find('StartTime').text)
二、 iter 使用
for node in root.iter() :
pirnt(node.tag, node.attrib) 查询子子孙孙。
for node in root.find('country'):
print(node.tag, node.attrib) 查找孩子
for node in root:
print(node.tag, node.attrib) 只遍历节点的孩子节点
for node in root.iter('country'): ###只遍历符合名称为 country的子孙节点
print(node.tag)
三、解析XML
通过 XML.etree.ElementTree 解析
1 from xml.etree import ElementTree as ET
2 #读取文件内容到字符串 3 str_xml = open('xo.xml','r').read()
4 #字符串解析为element 对象. a 为xml的根节点 5 a = ET.XML(str_xml) 6 print(type(a))
7 #通过iter拿到root的各个子孙 8 for b in a.iter(): 9 print(b)
1 from xml.etree import ElementTree as ET
2 #直接解析XML文件。生成ElementTree 的对象 3 xml = ET.parse('xo.xml') 4 print(type(xml))
5 #得到root根节点 6 root = xml.getroot()
7 #iter 拿到子孙节点 8 for b in root.iter(): 9 print(b)
四、操作XML
1: XML 功能列表
XML 是节点嵌套格式。针对每一个节点均有下面的功能
1 class Element: 2 """An XML element. 3 4 This class is the reference implementation of the Element interface. 5 6 An element's length is its number of subelements. That means if you 7 want to check if an element is truly empty, you should check BOTH 8 its length AND its text attribute. 9 10 The element tag, attribute names, and attribute values can be either 11 bytes or strings. 12 13 *tag* is the element name. *attrib* is an optional dictionary containing 14 element attributes. *extra* are additional element attributes given as 15 keyword arguments. 16 17 Example form: 18 <tag attrib>text<child/>...</tag>tail 19 20 """ 21 22 tag = None 23 24 节点名称 25 """The element's name.""" 26 27 attrib = None 28 29 节点属性 30 """Dictionary of the element's attributes.""" 31 32 text = None 33 34 节点内容 35 """ 36 Text before first subelement. This is either a string or the value None. 37 Note that if there is no text, this attribute may be either 38 None or the empty string, depending on the parser. 39 40 """ 41 42 tail = None 43 """ 44 Text after this element's end tag, but before the next sibling element's 45 start tag. This is either a string or the value None. Note that if there 46 was no text, this attribute may be either None or an empty string, 47 depending on the parser. 48 49 """ 50 51 def __init__(self, tag, attrib={}, **extra): 52 if not isinstance(attrib, dict): 53 raise TypeError("attrib must be dict, not %s" % ( 54 attrib.__class__.__name__,)) 55 attrib = attrib.copy() 56 attrib.update(extra) 57 self.tag = tag 58 self.attrib = attrib 59 self._children = [] 60 61 def __repr__(self): 62 return "<%s %r at %#x>" % (self.__class__.__name__, self.tag, id(self)) 63 64 def makeelement(self, tag, attrib): 65 """Create a new element with the same type. 66 67 添加一个新的节点 68 69 70 *tag* is a string containing the element name. 71 *attrib* is a dictionary containing the element attributes. 72 73 Do not call this method, use the SubElement factory function instead. 74 75 """ 76 return self.__class__(tag, attrib) 77 78 def copy(self): 79 """Return copy of current element. 80 81 This creates a shallow copy. Subelements will be shared with the 82 original tree. 83 84 """ 85 elem = self.makeelement(self.tag, self.attrib) 86 elem.text = self.text 87 elem.tail = self.tail 88 elem[:] = self 89 return elem 90 91 def __len__(self): 92 return len(self._children) 93 94 def __bool__(self): 95 warnings.warn( 96 "The behavior of this method will change in future versions. " 97 "Use specific 'len(elem)' or 'elem is not None' test instead.", 98 FutureWarning, stacklevel=2 99 ) 100 return len(self._children) != 0 # emulate old behaviour, for now 101 102 def __getitem__(self, index): 103 return self._children[index] 104 105 def __setitem__(self, index, element): 106 # if isinstance(index, slice): 107 # for elt in element: 108 # assert iselement(elt) 109 # else: 110 # assert iselement(element) 111 self._children[index] = element 112 113 def __delitem__(self, index): 114 del self._children[index] 115 116 def append(self, subelement): 117 """Add *subelement* to the end of this element. 118 119 追加节点。 追加的内容必须是element 对象。 因此前面需要有生成element 对象的步骤。 120 121 122 The new element will appear in document order after the last existing 123 subelement (or directly after the text, if it's the first subelement), 124 but before the end tag for this element. 125 126 """ 127 self._assert_is_element(subelement) 128 self._children.append(subelement) 129 130 def extend(self, elements): 131 132 批量的添加节点 133 """Append subelements from a sequence. 134 135 *elements* is a sequence with zero or more elements. 136 137 """ 138 for element in elements: 139 self._assert_is_element(element) 140 self._children.extend(elements) 141 142 def insert(self, index, subelement): 143 """Insert *subelement* at position *index*.""" 144 145 插入节点。提供插入的序号和element对象 146 from xml.etree import ElementTree as ET 147 148 xml = ET.parse('xo.xml') 149 root = xml.getroot() 150 son = root.makeelement('son',{'attr1':'abc'}) 151 son2 = root.makeelement('son2',{'attr2':'12'}) 152 for node in root.iter('country'): 153 node.insert(1,son2) 154 root.append(son) 155 xml.write('xo.xml') 156 157 self._assert_is_element(subelement) 158 self._children.insert(index, subelement) 159 160 def _assert_is_element(self, e): 161 # Need to refer to the actual Python implementation, not the 162 # shadowing C implementation. 163 if not isinstance(e, _Element_Py): 164 raise TypeError('expected an Element, not %s' % type(e).__name__) 165 166 def remove(self, subelement): 167 """Remove matching subelement. 168 169 删除节点。 删除节点只能删除自己的孩子节点。 且只能删除element 对象。因此需要通过find找到这个节点,在进行删除。 170 b = root.find('country') 171 print(b) 172 c = b.find('son2') 173 b.remove(b.find('son2')) 174 175 Unlike the find methods, this method compares elements based on 176 identity, NOT ON tag value or contents. To remove subelements by 177 other means, the easiest way is to use a list comprehension to 178 select what elements to keep, and then use slice assignment to update 179 the parent element. 180 181 ValueError is raised if a matching element could not be found. 182 183 """ 184 # assert iselement(element) 185 self._children.remove(subelement) 186 187 def getchildren(self): 188 """(Deprecated) Return all subelements. 189 190 Elements are returned in document order. 191 192 """ 193 warnings.warn( 194 "This method will be removed in future versions. " 195 "Use 'list(elem)' or iteration over elem instead.", 196 DeprecationWarning, stacklevel=2 197 ) 198 return self._children 199 200 def find(self, path, namespaces=None): 201 """Find first matching element by tag name or path. 202 查找第一个符合条件的孩子节点 203 204 *path* is a string having either an element tag or an XPath, 205 *namespaces* is an optional mapping from namespace prefix to full name. 206 207 Return the first matching element, or None if no element was found. 208 209 """ 210 return ElementPath.find(self, path, namespaces) 211 212 def findtext(self, path, default=None, namespaces=None): 213 """Find text for first matching element by tag name or path. 214 查找第一个符合条件的孩子节点的文本内容 215 216 *path* is a string having either an element tag or an XPath, 217 *default* is the value to return if the element was not found, 218 *namespaces* is an optional mapping from namespace prefix to full name. 219 220 Return text content of first matching element, or default value if 221 none was found. Note that if an element is found having no text 222 content, the empty string is returned. 223 224 """ 225 return ElementPath.findtext(self, path, default, namespaces) 226 227 def findall(self, path, namespaces=None): 228 """Find all matching subelements by tag name or path. 229 查找所有符合条件的节点,并返回一个列表 230 231 *path* is a string having either an element tag or an XPath, 232 *namespaces* is an optional mapping from namespace prefix to full name. 233 234 Returns list containing all matching elements in document order. 235 236 """ 237 return ElementPath.findall(self, path, namespaces) 238 239 def iterfind(self, path, namespaces=None): 240 """Find all matching subelements by tag name or path. 241 查找所有符合条件的节点,并返回一个迭代器 242 243 *path* is a string having either an element tag or an XPath, 244 *namespaces* is an optional mapping from namespace prefix to full name. 245 246 Return an iterable yielding all matching elements in document order. 247 248 """ 249 return ElementPath.iterfind(self, path, namespaces) 250 251 def clear(self): 252 """Reset element. 253 清除所有节点 254 This function removes all subelements, clears all attributes, and sets 255 the text and tail attributes to None. 256 257 """ 258 self.attrib.clear() 259 self._children = [] 260 self.text = self.tail = None 261 262 def get(self, key, default=None): 263 """Get element attribute. 264 得到属性值 265 Equivalent to attrib.get, but some implementations may handle this a 266 bit more efficiently. *key* is what attribute to look for, and 267 *default* is what to return if the attribute was not found. 268 269 Returns a string containing the attribute value, or the default if 270 attribute was not found. 271 272 """ 273 return self.attrib.get(key, default) 274 275 def set(self, key, value): 276 """Set element attribute. 277 设置属性值 278 Equivalent to attrib[key] = value, but some implementations may handle 279 this a bit more efficiently. *key* is what attribute to set, and 280 *value* is the attribute value to set it to. 281 282 """ 283 self.attrib[key] = value 284 285 def keys(self): 286 """Get list of attribute names. 287 得到所有的属性名称 288 Names are returned in an arbitrary order, just like an ordinary 289 Python dict. Equivalent to attrib.keys() 290 291 """ 292 return self.attrib.keys() 293 294 def items(self): 295 得到所有的属性名称和值的键值对 296 """Get element attributes as a sequence. 297 298 The attributes are returned in arbitrary order. Equivalent to 299 attrib.items(). 300 301 Return a list of (name, value) tuples. 302 303 """ 304 return self.attrib.items() 305 306 def iter(self, tag=None): 307 """Create tree iterator. 308 得到所有子孙节点,并返回一个迭代器 309 310 The iterator loops over the element and all subelements in document 311 order, returning all elements with a matching tag. 312 313 If the tree structure is modified during iteration, new or removed 314 elements may or may not be included. To get a stable set, use the 315 list() function on the iterator, and loop over the resulting list. 316 317 *tag* is what tags to look for (default is to return all elements) 318 319 Return an iterator containing all the matching elements. 320 321 """ 322 if tag == "*": 323 tag = None 324 if tag is None or self.tag == tag: 325 yield self 326 for e in self._children: 327 yield from e.iter(tag) 328 329 # compatibility 330 def getiterator(self, tag=None): 331 # Change for a DeprecationWarning in 1.4 332 warnings.warn( 333 "This method will be removed in future versions. " 334 "Use 'elem.iter()' or 'list(elem.iter())' instead.", 335 PendingDeprecationWarning, stacklevel=2 336 ) 337 return list(self.iter(tag)) 338 339 def itertext(self): 340 """Create text iterator. 341 得到所有子孙节点的内容,并返回一个迭代器 342 The iterator loops over the element and all subelements in document 343 order, returning all inner text. 344 345 """ 346 tag = self.tag 347 if not isinstance(tag, str) and tag is not None: 348 return 349 if self.text: 350 yield self.text 351 for e in self: 352 yield from e.itertext() 353 if e.tail: 354 yield e.tail 355 356 357 def SubElement(parent, tag, attrib={}, **extra): 358 """Subelement factory which creates an element instance, and appends it 359 to an existing parent. 360 直接给某节点添加孩子节点。 361 362 The element tag, attribute names, and attribute values can be either 363 bytes or Unicode strings. 364 365 *parent* is the parent element, *tag* is the subelements name, *attrib* is 366 an optional directory containing element attributes, *extra* are 367 additional attributes given as keyword arguments. 368 369 """ 370 attrib = attrib.copy() 371 attrib.update(extra) 372 element = parent.makeelement(tag, attrib) 373 parent.append(element) 374 return element 375 376 377 def Comment(text=None): 378 """Comment element factory. 379 380 This function creates a special element which the standard serializer 381 serializes as an XML comment. 382 383 *text* is a string containing the comment string. 384 385 """ 386 element = Element(Comment) 387 element.text = text 388 return element 389 390 391 def ProcessingInstruction(target, text=None): 392 """Processing Instruction element factory. 393 394 This function creates a special element which the standard serializer 395 serializes as an XML comment. 396 397 *target* is a string containing the processing instruction, *text* is a 398 string containing the processing instruction contents, if any. 399 400 """ 401 element = Element(ProcessingInstruction) 402 element.text = target 403 if text: 404 element.text = element.text + " " + text 405 return element 406 407 PI = ProcessingInstruction
2: 遍历所有节点
1 from xml.etree import ElementTree as ET 2 3 #解析方式一 4 """ 5 打开文件,读取XML内容 6 转化为字符串在转换为elemnt类型 7 """ 8 9 str_xml = open('xo.xml').read() 10 11 root = ET.XML(str_xml) 12 13 #解析方式二 14 """ 15 直接将解析xml文件 得到ElementTree 类型 16 getroot()得到文件根节点 17 """ 18 tree = ET.parse('xo.xml') 19 20 root = tree.getroot() 21 22 23 24 #######操作######## 25 #顶层标签 26 print(root.tag) 27 28 #遍历XML文档第二层。root的孩子 29 for node in root: 30 #第二层所有的节点标签名称和属性 31 print(node.tag,node.attrib) 32 #遍历 33 for child in node: 34 #第三层所有节点标签名称和属性 35 print(child.tag, child.attrib)
3:遍历指定节点
1 #遍历指定节点的子孙 2 for node in root.iter('rank'): 3 print(node.tag,node.attrib) 4 5 #遍历指定节点的孩子 6 for node in root.find('country'): 7 print(node.tag,node.attrib)
4:编辑节点内容
由于节点内容的编辑均在内存中进行,因此在没有执行write前,均不改变源文件内容。
解析字符串方式 属性值的设置、添加、删除
1 from xml.etree import ElementTree as ET 2 3 #####解析方式一####### 4 #直接解析文件,得到ElementTree对象 5 tree = ET.parse('xo.xml') 6 7 #得到root根节点 8 root = tree.getroot() 9 10 #顶层标签 11 print(root.tag) 12 13 #循环所有year节点 14 15 for node in root.iter('year'): 16 #year自增加1 17 new_year = int(node.text)+1 18 node.text = str(new_year) 19 20 #设置node 属性 21 node.set('name','yy') 22 node.set('age',18) 23 print(node.tag, node.attrib) 24 25 #删除节点属性 26 del node.attrib['age'] 27 print(node.tag, node.attrib) 28 29 #####写回xml文件 30 tree.write('newxo.xml')
5:删除节点
1 from xml.etree import ElementTree as ET 2 ##########解析字符串的方式打开############ 3 #打开文件内容,读取xml文件 4 str_xml = open('xo.xml','r').read() 5 6 root = ET.XML(str_xml) 7 8 for node in root.findall('country'): 9 #获得下一个节点内容rank 10 rank = int(node.find('rank').text) 11 12 if rank > 50: 13 #删除指定节点 14 root.remove(node) 15 16 ###########文件写回############### 17 # #由于字符串解析方式,没有生成一个ElementTree对象, 18 # 因此需要单独实例化一个对象,并指定是为root生成 19 tree = ET.ElementTree(root) 20 tree.write('xo.xml')
1 from xml.etree import ElementTree as ET 2 3 #直接解析xml 文件 4 5 tree = ET.parse('xo.xml') 6 7 root = tree.getroot() 8 9 for node in root.findall('country'): 10 #获得下一个节点内容rank 11 rank = int(node.find('rank').text) 12 13 if rank > 50: 14 #删除指定节点 15 root.remove(node) 16 17 ###########文件写回############### 18 tree.write('xo.xml')
6:创建XML文档
1 from xml.etree import ElementTree as ET 2 3 #创建根节点 4 root = ET.Element('data') 5 6 #创建第一层,第一个节点 7 first = ET.Element('first',{'name':'大儿子'}) 8 second = ET.Element('second',{'name':'二儿子'}) 9 10 #将第一层节点添加到根节点 11 root.append(first) 12 root.append(second) 13 14 grandfirst = ET.Element('grandfirst',{'name':'大孙子'}) 15 grandsecond = ET.Element('grandsecond',{'name':'二孙子'}) 16 17 #将第二层节点添加到第一层节点 18 first.append(grandfirst) 19 second.append(grandsecond) 20 21 #创建root为根节点的tree 22 tree = ET.ElementTree(root) 23 tree.write('new1.xml',encoding = 'UTF-8')
1 from xml.etree import ElementTree as ET 2 3 #创建根节点 4 root = ET.Element('data') 5 6 #创建第一层节点 7 8 first = root.makeelement('first',{'name':'大儿子'}) 9 second = root.makeelement('second',{'name':'二儿子'}) 10 11 #将一层节点添加到root 12 root.append(first) 13 root.append(second) 14 15 #创建二层节点 16 grandfirst = first.makeelement('grandfirst',{'name':'大孙子'}) 17 grandsecond = second.makeelement('grandsecond',{'name':'二孙子'}) 18 19 #将二层节点添加到一层节点 20 first.append(grandfirst) 21 second.append(grandsecond) 22 23 #将文件写回. 建立以root 为根的tree 24 tree = ET.ElementTree(root) 25 tree.write('new2.xml',encoding = 'utf-8')
1 from xml.etree import ElementTree as ET 2 3 #创建根节点 4 5 root = ET.Element('data') 6 7 #直接给root 创建儿子节点 8 9 first = ET.SubElement(root,'first',{'name':'大儿子'}) 10 second = ET.SubElement(root,'second',{'name':'二儿子'}) 11 12 #直接给儿子创建孙子节点 13 14 grandfirst = ET.SubElement(first,'grandfirst',{'name':'大孙子'}) 15 grandsecond = ET.SubElement(second,'grandsecond',{'name':'二孙子'}) 16 17 #写回文件 18 tree = ET.ElementTree(root) 19 20 tree.write('new3.xml',encoding = 'utf-8')
7:设置缩进
import minidom,将节点转换为字符串进行美化后,在输出到文件。
1 from xml.etree import ElementTree as ET 2 from xml.dom import minidom 3 4 def pretty(elem): 5 """ 6 将节点转换为字符串,并添加缩进 7 8 :param elem: 9 :return: 10 """ 11 rough_string = ET.tostring(elem, 'utf-8') 12 reparsed = minidom.parseString(rough_string) 13 #print(type(reparsed)) 14 return reparsed.toprettyxml(indent = '\t') 15 16 #创建根节点 17 18 root = ET.Element('data') 19 20 #直接给root 创建儿子节点 21 22 first = ET.SubElement(root,'first',{'name':'大儿子'}) 23 second = ET.SubElement(root,'second',{'name':'二儿子'}) 24 25 #直接给儿子创建孙子节点 26 27 grandfirst = ET.SubElement(first,'grandfirst',{'name':'大孙子'}) 28 grandsecond = ET.SubElement(second,'grandsecond',{'name':'二孙子'}) 29 30 31 #写回文件. 调用pretty 美化格式 32 raw_str = pretty(root) 33 print(type(raw_str)) 34 35 #打开文件,写回 36 f = open('new5.xml','w',encoding = 'utf-8') 37 f.write(raw_str) 38 f.close()
8:命名空间
避免XML标签名称重复
1 from xml.etree import ElementTree as ET 2 3 ET.register_namespace('com','http://www.baiu.com') 4 5 #创建树形结构 6 7 root = ET.Element('{http://www.baiu.com}data') 8 9 body = ET.SubElement(root,'{http://www.baiu.com}first', attrib = {'{http://www.baiu.com}name':'儿子'}) 10 11 tree = ET.ElementTree(root) 12 13 tree.write('new7.xml',encoding = 'utf-8')
9: 练习XML request 带参数
1 #!/usr/bin/evn python 2 #-*- coding:utf-8 -*- 3 import requests 4 from xml.etree import ElementTree as ET 5 6 def getarea(): 7 """ 8 打印地区和所在编号 9 :return: 10 """ 11 req = requests.get('http://www.webxml.com.cn/webservices/ChinaTVprogramWebService.asmx/getAreaDataSet') 12 req.encoding = 'utf-8' 13 areas = req.text 14 arearoot = ET.XML(areas) 15 arealist = [] 16 for node in arearoot.iter('AreaList'): 17 areaid = node.find('areaID').text 18 area = node.find('Area').text 19 arealist.append({areaid:area}) 20 21 for item in arealist: 22 for k,v in item.items(): 23 print('%s 编号:%s' %(v, k)) 24 25 return arealist 26 27 def getstation(areaid): 28 """ 29 打印电视台列表 30 :param areaid: 区域id 31 :return: 32 """ 33 payload = {'theAreaID': areaid} 34 req = requests.get('http://www.webxml.com.cn/webservices/ChinaTVprogramWebService.asmx/getTVstationDataSet',params=payload) 35 req.encoding = 'utf-8' 36 stations = req.text 37 tvstation = ET.XML(stations) 38 stationlist = [] 39 for node in tvstation.iter('TvStation'): 40 stationid = node.find('tvStationID').text 41 stationname = node.find('tvStationName').text 42 stationlist.append({stationid: stationname}) 43 44 for item in stationlist: 45 for k , v in item.items(): 46 print('%s 编号:%s' % (v , k)) 47 48 return stationlist 49 50 def gettvchannel(stationid): 51 """ 52 打印频道 53 :param stationid: 电视台id 54 :return: 55 """ 56 payload = {'theTVstationID': stationid} 57 req = requests.get('http://www.webxml.com.cn/webservices/ChinaTVprogramWebService.asmx/getTVchannelDataSet',params=payload) 58 req.encoding = 'utf-8' 59 tvchannel = req.text 60 channels = ET.XML(tvchannel) 61 channellist = [] 62 for node in channels.iter('TvChanne'): 63 channelid = node.find('tvChannelID').text 64 channelname = node.find('tvChannel').text 65 channellist.append({channelid: channelname}) 66 67 for item in channellist: 68 for k , v in item.items(): 69 print('%s 编号:%s' % (v , k)) 70 71 return channellist 72 73 def getTVprogramDateSet(channelid): 74 """ 75 打印节目列表 76 :param channelid: 频道id 77 :return: 78 """ 79 payload = {'theTVchannelID': channelid,'theDate':'','userID':''} 80 req = requests.get('http://www.webxml.com.cn/webservices/ChinaTVprogramWebService.asmx/getTVprogramDateSet',params=payload) 81 req.encoding = 'utf-8' 82 program = req.text 83 programdata = ET.XML(program) 84 programdatalist = {} 85 for node in programdata.iter('tvProgramTable'): 86 playTime = node.find('playTime').text + node.find('meridiem').text 87 tvProgram = node.find('tvProgram').text 88 programdatalist[playTime] = tvProgram 89 90 91 for k,v in sorted(programdatalist.items()): 92 print(k,v) 93 return programdatalist 94 95 96 def exec(): 97 """ 98 执行函数 99 :return: 100 """ 101 getarea() 102 while True: 103 area = input('请输入地域编号,退出请按*\n') 104 if area.isdigit(): 105 areas = getstation(area) 106 if len(areas) > 0: 107 while True: 108 station = input('请输入电视台编号,返回上一层请按&*\n') 109 110 if station.isdigit(): 111 stations = gettvchannel(station) 112 if(len(stations)) >0 : 113 while True: 114 channel = input('请输入频道编号,返回上一层请按*\n') 115 if channel.isdigit(): 116 programdatalist = getTVprogramDateSet(channel) 117 if len(programdatalist) == 0: 118 print('节目列表为空') 119 elif channel == '*': 120 break 121 else: 122 print('输入有误!') 123 else: 124 print('您输入的电视台不存在或者该电视台无频道!') 125 elif station =='*': 126 break 127 128 else: 129 print('输入有误!') 130 else: 131 print('您输入的地域不存在或者该区无电视台') 132 elif area == '*': 133 break 134 else: 135 print('输入有错误!') 136 137 138 139 if __name__ == '__main__': 140 exec()

浙公网安备 33010602011771号