weibo.py 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151
  1. # coding: utf-8
  2. from __future__ import unicode_literals
  3. from .common import InfoExtractor
  4. from urllib.request import Request
  5. from urllib.parse import urlencode
  6. from urllib import parse
  7. import json
  8. import random as rnd
  9. from os import path
  10. import re
  11. from ..utils import (
  12. js_to_json,
  13. )
  14. class WeiboIE(InfoExtractor):
  15. _VALID_URL = r'https?://weibo\.com/[0-9]+/(?P<id>[a-zA-Z0-9]+)'
  16. _TEST = {
  17. 'url': 'https://weibo.com/6275294458/Fp6RGfbff?type=comment',
  18. 'info_dict': {
  19. 'id': 'Fp6RGfbff',
  20. 'ext': 'mp4',
  21. 'title': 'You should have servants to massage you,... 来自Hosico_猫 - 微博',
  22. }
  23. }
  24. def _real_extract(self, url):
  25. video_id = self._match_id(url)
  26. headers = {
  27. 'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8',
  28. 'Accept-Encoding': 'gzip, deflate, br',
  29. 'Accept-Language': 'en,zh-CN;q=0.9,zh;q=0.8',
  30. 'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.84 Safari/537.36',
  31. 'Upgrade-Insecure-Requests': '1',
  32. }
  33. # to get Referer url for genvisitor
  34. webpage,urlh = self._download_webpage_handle(url, video_id, headers=headers, note="first visit the page")
  35. visitor_url = urlh.geturl()
  36. data = urlencode({
  37. "cb": "gen_callback",
  38. "fp": '{"os":"2","browser":"Gecko57,0,0,0","fonts":"undefined","screenInfo":"1440*900*24","plugins":""}',
  39. }).encode()
  40. headers = {
  41. 'Accept-Encoding': 'gzip, deflate, br',
  42. 'Accept': '*/*',
  43. 'Referer': visitor_url,
  44. }
  45. r_genvisitor = Request(
  46. 'https://passport.weibo.com/visitor/genvisitor',
  47. data = data,
  48. headers = headers,
  49. method = 'POST'
  50. )
  51. webpage,urlh = self._download_webpage_handle(r_genvisitor, video_id, note="gen visitor")
  52. p = webpage.split("&&")[1] # split "gen_callback && gen_callback(...)"
  53. i1 = p.find('{')
  54. i2 = p.rfind('}')
  55. j = p[i1:i2+1] # get JSON object
  56. d = json.loads(j)
  57. tid = d["data"]["tid"]
  58. cnfd = "%03d" % d["data"]["confidence"]
  59. param = urlencode({
  60. 'a': 'incarnate',
  61. 't': tid,
  62. 'w': 2,
  63. 'c': cnfd,
  64. 'cb': 'cross_domain',
  65. 'from': 'weibo',
  66. '_rand': rnd.random()
  67. })
  68. gencallback_url = "https://passport.weibo.com/visitor/visitor?" + param
  69. webpage,urlh = self._download_webpage_handle(gencallback_url, video_id, note="gen callback")
  70. webpage,urlh = self._download_webpage_handle(url, video_id, headers=headers, note="retry to visit the page")
  71. # TODO more code goes here, for example ...
  72. title = self._html_search_regex(r'<title>(.+?)</title>', webpage, 'title')
  73. video_sources_text = self._search_regex("video-sources=\\\\\"(.+?)\"", webpage, 'video_sources')
  74. video_formats = parse.parse_qs(video_sources_text)
  75. formats = []
  76. supported_resolutions = ['720', '480']
  77. for res in supported_resolutions:
  78. f = video_formats.get(res)
  79. if isinstance(f, list):
  80. if len(f) > 0:
  81. vid_url = f[0]
  82. formats.append({
  83. 'url': vid_url,
  84. 'format': 'mp4',
  85. 'height': int(res),
  86. })
  87. self._sort_formats(formats)
  88. uploader = self._og_search_property('nick-name', webpage, 'uploader', default = None)
  89. return {
  90. 'id': video_id,
  91. 'title': title,
  92. 'uploader': uploader,
  93. 'formats': formats
  94. # TODO more properties (see youtube_dl/extractor/common.py)
  95. }
  96. class WeiboMobileIE(InfoExtractor):
  97. _VALID_URL = r'https?://m.weibo.cn/status/(?P<id>[0-9]+)(\?.+)?'
  98. _TEST = {
  99. 'url': 'https://m.weibo.cn/status/4189191225395228?wm=3333_2001&sourcetype=weixin&featurecode=newtitle&from=singlemessage&isappinstalled=0',
  100. 'info_dict': {
  101. 'id': '4189191225395228',
  102. 'ext': 'mp4',
  103. 'title': '午睡当然是要甜甜蜜蜜的啦',
  104. 'uploader': '柴犬柴犬'
  105. }
  106. }
  107. def _real_extract(self, url):
  108. video_id = self._match_id(url)
  109. headers = {
  110. 'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8',
  111. 'Accept-Encoding': 'gzip, deflate, br',
  112. 'Accept-Language': 'en,zh-CN;q=0.9,zh;q=0.8',
  113. 'Upgrade-Insecure-Requests': '1',
  114. }
  115. # to get Referer url for genvisitor
  116. webpage,urlh = self._download_webpage_handle(url, video_id, headers=headers, note="visit the page")
  117. js_code = self._search_regex(r'var\s+\$render_data\s*=\s*\[({.*})\]\[0\] \|\| {};', webpage, 'js_code', flags = re.DOTALL)
  118. weibo_info = self._parse_json(js_code, video_id, transform_source=js_to_json)
  119. page_info = weibo_info['status']['page_info']
  120. title = weibo_info['status']['status_title']
  121. format = {
  122. 'url': page_info['media_info']['stream_url'],
  123. 'format': 'mp4',
  124. }
  125. formats = [format]
  126. uploader = weibo_info['status']['user']['screen_name']
  127. return {
  128. 'id': video_id,
  129. 'title': title,
  130. 'uploader': uploader,
  131. 'formats': formats
  132. # TODO more properties (see youtube_dl/extractor/common.py)
  133. }