py_sport.py 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201
  1. #coding=utf-8
  2. #!/usr/bin/python
  3. import sys
  4. sys.path.append('..')
  5. from base.spider import Spider
  6. import json
  7. import base64
  8. import random
  9. import requests
  10. import urllib.parse
  11. class Spider(Spider): # 元类 默认的元类 type
  12. def getName(self):
  13. return "体育直播"
  14. def init(self,extend=""):
  15. print("============{0}============".format(extend))
  16. pass
  17. def isVideoFormat(self,url):
  18. pass
  19. def manualVideoCheck(self):
  20. pass
  21. def homeContent(self,filter):
  22. result = {}
  23. cateManual = {
  24. "体育直播": "全部"
  25. }
  26. classes = []
  27. for k in cateManual:
  28. classes.append({
  29. 'type_name':k,
  30. 'type_id':cateManual[k]
  31. })
  32. result['class'] = classes
  33. if(filter):
  34. result['filters'] = self.config['filter']
  35. return result
  36. def homeVideoContent(self):
  37. result = {}
  38. return result
  39. def categoryContent(self,tid,pg, filter,extend):
  40. result = {}
  41. if int(pg) > 1:
  42. return result
  43. rsp = self.fetch('http://itiyu5.tv/spweb/schedule', headers=self.header)
  44. root = self.html(self.cleanText(rsp.text))
  45. dataList = root.xpath("//div[@class='fixtures']/div[@class='box']")
  46. dateList = root.xpath("//div[contains(@class,'subhead')]")
  47. videos = []
  48. utc_offset = self.fetch('http://worldtimeapi.org/api/timezone/Australia/Sydney', headers=self.header).json()['utc_offset']
  49. hour_offset = int(utc_offset.split(':')[0][1:]) - 8
  50. for data in dataList:
  51. pos = dataList.index(data)
  52. for video in data.xpath(".//div[@class='list']/ul/li"):
  53. infosList = video.xpath(".//div[@class='team']/div")
  54. stime = video.xpath(".//p[@class='name']/span/text()")[0].strip()
  55. sdate = dateList[pos].xpath('.//text()')[0].split()[0].strip()
  56. hour = stime.split(':')[0]
  57. if int(hour) < hour_offset:
  58. sdate = sdate.replace(sdate[3:-1], str(int(sdate[3:-1]) - 1))
  59. stime = str(24 - hour_offset + int(hour)) + ':' + stime.split(':')[1]
  60. else:
  61. hour = str(int(hour) - hour_offset)
  62. if len(hour) == 1:
  63. hour = '0' + hour
  64. stime = hour + ':' + stime.split(':')[1]
  65. rid = video.xpath(".//p[contains(@class,'btn')]/a/@href")[0]
  66. state = video.xpath(".//p[contains(@class,'btn')]/a/text()")[0].strip()
  67. if len(infosList) != 2:
  68. home = infosList[0].xpath('.//span/text()')[0].strip()
  69. away = infosList[2].xpath('.//span/text()')[0].strip()
  70. cover = infosList[0].xpath('.//img/@src')[0]
  71. name = home + 'VS' + away
  72. else:
  73. cover = 'https://s1.ax1x.com/2022/10/07/x3NPUO.png'
  74. name = infosList[1].xpath('.//text()')[0].strip()
  75. if state != '已结束':
  76. videos.append({
  77. "vod_id": rid,
  78. "vod_name": name,
  79. "vod_pic": cover,
  80. "vod_remarks": '[{}]|{}'.format(sdate, stime)
  81. })
  82. result['list'] = videos
  83. result['page'] = pg
  84. result['pagecount'] = 9999
  85. result['limit'] = 90
  86. result['total'] = 999999
  87. return result
  88. def detailContent(self, array):
  89. for i in range(1, 5):
  90. rsp = self.fetch('http://itiyu5.tv{}/vid/{}'.format(array[0], i), headers=self.header)
  91. if 'vid/{}'.format(i) not in rsp.text or not '\'url\': ' in rsp.text:
  92. title = '比赛尚未开始'
  93. purl = 'http://0.0.0.0'
  94. else:
  95. purl = self.regStr(reg=r"\'url\': \"(.*?)\"", src=rsp.text)
  96. title = self.regStr(reg=r"\"title\": \"(.*?)\"", src=rsp.text)
  97. if purl == '':
  98. rid = self.regStr(reg=r'config\.iurl = \"(.*?)\"', src=rsp.text)
  99. if '.m3u' in rid:
  100. if rid.count('http') != 1:
  101. replstr = self.regStr(reg=r'(http.*?)http', src=rid)
  102. purl = rid.replace(replstr, '')
  103. else:
  104. rid = self.regStr(reg=r'id=(.*)', src=rid)
  105. rsp = self.fetch('https://info.zb.video.qq.com/?cmd=4', headers=self.header)
  106. country = json.loads(rsp.text)['country']
  107. province = json.loads(rsp.text)['province']
  108. city = json.loads(rsp.text)['city']
  109. ip = json.loads(rsp.text)['ip']
  110. rsp = self.fetch('https://geo.yolll.com/geo', headers=self.header)
  111. cf_ua = json.loads(rsp.text)['ua']
  112. cf_cc = json.loads(rsp.text)['ip']
  113. cf_ip = json.loads(rsp.text)['cc']
  114. rnd = round(random.random() * 100000)
  115. param = {
  116. 'type': 'stream',
  117. 'id': rid,
  118. 'rnd': rnd,
  119. 'ip': ip,
  120. 'country': country,
  121. 'province': province,
  122. 'city': city,
  123. 'tx_ip': ip,
  124. 'tx_country': country,
  125. 'tx_province': province,
  126. 'tx_city': city,
  127. 'cf_ip': cf_ip,
  128. 'cf_cc': cf_cc,
  129. 'cf_ua': cf_ua,
  130. 'ref': 'direct',
  131. 'ua': 'web',
  132. }
  133. self.header['Referer'] = 'https://v.stnye.cc/'
  134. self.header['Content-Type'] = 'application/x-www-form-urlencoded; charset=UTF-8'
  135. rsp = self.post('https://cdn.dianshunxinxi.com/data/live.php', data=param, headers=self.header)
  136. jo = json.loads(rsp.text)
  137. if jo['status'] != 'success':
  138. return ''
  139. else:
  140. purl = base64.b64decode(urllib.parse.unquote(jo['playurl'])).decode('utf-8')
  141. purl = base64.b64decode(purl).decode('utf-8')
  142. if '.m3u' in purl or purl == 'http://0.0.0.0':
  143. break
  144. vod = {
  145. "vod_id":array[0],
  146. "vod_name":title,
  147. "vod_pic":'https://s1.ax1x.com/2022/10/07/x3NPUO.png',
  148. "type_name":'',
  149. "vod_year":'',
  150. "vod_area":"",
  151. "vod_remarks":'',
  152. "vod_actor":"",
  153. "vod_director":'',
  154. "vod_content":""
  155. }
  156. findurl = False
  157. if purl != '' and purl != 'http://0.0.0.0':
  158. rsp = self.fetch(purl, headers=self.header)
  159. if '.m3u8' in rsp.text and title != '比赛尚未开始':
  160. findurl = True
  161. while findurl:
  162. purl = rsp.text.strip('\n').split('\n')[-1]
  163. rsp = requests.get(purl, headers=self.header, verify=False)
  164. if '.m3u8' not in rsp.text:
  165. findurl = False
  166. vod['vod_play_from'] = '体育直播'
  167. vod['vod_play_url'] = '{}${}'.format(title.replace(' ', ''), purl)
  168. result = {
  169. 'list':[
  170. vod
  171. ]
  172. }
  173. return result
  174. def searchContent(self,key,quick):
  175. result = {
  176. 'list':[]
  177. }
  178. return result
  179. def playerContent(self,flag,id,vipFlags):
  180. result = {}
  181. result["parse"] = 0
  182. result["playUrl"] = ''
  183. result["url"] = id
  184. result["header"] = ''
  185. return result
  186. config = {
  187. "player": {},
  188. "filter": {}
  189. }
  190. header = {
  191. "User-Agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/94.0.4606.54 Safari/537.36"
  192. }
  193. def localProxy(self,param):
  194. return [200, "video/MP2T", action, ""]