hksp_author.py 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186
  1. import os
  2. import re
  3. import base64
  4. import json
  5. import random
  6. import sys
  7. import datetime
  8. import time
  9. import uuid
  10. import requests
  11. from fake_useragent import FakeUserAgent
  12. sys.path.append(os.getcwd())
  13. from common.video_item import VideoItem
  14. from common import PiaoQuanPipeline, AliyunLogger
  15. from common.mq import MQ
  16. class HaoKaoVideoAccount:
  17. def __init__(self, platform, mode, rule_dict, user_dict, env):
  18. self.account_id = user_dict["link"]
  19. self.platform = platform
  20. self.mode = mode
  21. self.rule_dict = rule_dict
  22. self.user_dict = user_dict
  23. self.env = env
  24. self.download_cnt = 0
  25. self.mq = MQ(topic_name="topic_crawler_etl_" + self.env)
  26. self.url_key = "guanghui456"
  27. # 解密
  28. def decrypt(self, ori_str):
  29. # base64解码
  30. base64_bytes = base64.b64decode(ori_str)
  31. crypt_str = base64_bytes.decode("utf-8")
  32. # 异或解密
  33. n = ""
  34. for i in range(len(crypt_str)):
  35. o = ord(crypt_str[i])
  36. s = ord(self.url_key[i % len(self.url_key)])
  37. n += chr(o ^ s)
  38. return n
  39. # 获取视频列表
  40. def get_video_list(self):
  41. page_limit = 10
  42. url = "https://haokan.baidu.com/web/author/listall"
  43. params = {
  44. "app_id": self.account_id, # 账号id
  45. "ctime": "", # 翻页指示,用时间戳表示,为空表示从头开始
  46. "rn": page_limit, # 每一页的页数,默认是 10
  47. "_api": 1
  48. }
  49. headers = {
  50. 'Accept': '*/*',
  51. 'Accept-Language': 'en,zh-CN;q=0.9,zh;q=0.8',
  52. 'Cache-Control': 'no-cache',
  53. 'Connection': 'keep-alive',
  54. 'Content-Type': 'application/x-www-form-urlencoded',
  55. 'Cookie': 'BIDUPSID=504D4A3A8D0584CA8C3BE27ACFED5323; PSTM=1695297510; BAIDUID=504D4A3A8D0584CA7398158209FA507F:FG=1; BAIDUID_BFESS=504D4A3A8D0584CA7398158209FA507F:FG=1; H_WISE_SIDS=213352_214793_110085_244721_236312_265883_265985_269905_271172_270102_234295_234207_272282_263618_272473_260335_273141_273244_273397_273481_275098_275007_275853_276196_275170_271562_253022_275870_277354_251972_277631_277642_277635_277611_275732_276665_275209_277554_259642_278057_278166_278163_278300_274784_275167_278263_272560_278573_278575_277542_278790_278388_256739_278920_279021_279045_278237_279267_276573_279367_279385_278392_274947_276269_278946_279086_279610_279605_279680_276983_279877_279307_279695_279945_279703_279975_279998_278249_278213_280132_280209_277699_280161_280227_274286_280405_280368_278674_280485_280541_270366_278414_276929_275856_280614_256223_280488_280636_276438_280560_277759_279896_280768_280809_279850_280771_280107_280583; H_WISE_SIDS_BFESS=213352_214793_110085_244721_236312_265883_265985_269905_271172_270102_234295_234207_272282_263618_272473_260335_273141_273244_273397_273481_275098_275007_275853_276196_275170_271562_253022_275870_277354_251972_277631_277642_277635_277611_275732_276665_275209_277554_259642_278057_278166_278163_278300_274784_275167_278263_272560_278573_278575_277542_278790_278388_256739_278920_279021_279045_278237_279267_276573_279367_279385_278392_274947_276269_278946_279086_279610_279605_279680_276983_279877_279307_279695_279945_279703_279975_279998_278249_278213_280132_280209_277699_280161_280227_274286_280405_280368_278674_280485_280541_270366_278414_276929_275856_280614_256223_280488_280636_276438_280560_277759_279896_280768_280809_279850_280771_280107_280583; sensorsdata2015jssdkcross=%7B%22distinct_id%22%3A%2218b98064c148fe-08a95b8d70a5fe-17525634-1901520-18b98064c151479%22%2C%22first_id%22%3A%22%22%2C%22props%22%3A%7B%22%24latest_traffic_source_type%22%3A%22%E7%9B%B4%E6%8E%A5%E6%B5%81%E9%87%8F%22%2C%22%24latest_search_keyword%22%3A%22%E6%9C%AA%E5%8F%96%E5%88%B0%E5%80%BC_%E7%9B%B4%E6%8E%A5%E6%89%93%E5%BC%80%22%2C%22%24latest_referrer%22%3A%22%22%7D%2C%22%24device_id%22%3A%2218b98064c148fe-08a95b8d70a5fe-17525634-1901520-18b98064c151479%22%7D; H_PS_PSSID=39624_39663_39684_39690_39676_39678_39713; BDORZ=B490B5EBF6F3CD402E515D22BCDA1598; hkpcSearch=%u674E%u6709%u8D22; BA_HECTOR=0h240k018l2ka0a000a00g0g1il6sn21q; ZFY=PnfJdvQrpMNOIoZw1LsOKMDW8:BWcrmDvtL60fANYxmQ:C; Hm_lvt_4aadd610dfd2f5972f1efee2653a2bc5=1699950106,1700038092; PC_TAB_LOG=video_details_page; COMMON_LID=c414c76cb1b11dfb04b7062a5ae09ce2; ab_sr=1.0.1_ZGEwNWY3OTFhZmNhNzZiN2YyZjljYjI3ZmE2YzRiZDA5NjY3YTI0OTdiMWM0ZWZhMjU3YWMzMThmZjU5YzQ5MDM0NDA4N2FmZWM5M2I0ZmQzZmE0ZWI2MjJkMjE0MDQ1ZTIyYmU5OGQ3OWY3ZDNlYTI2NmFiMGZlYTliODFmZmJiY2U0MDRmMzkwZWMzOTQxMTc0MDU3NmQ2ZWVlNjM3ZA==; reptileData=%7B%22data%22%3A%22636c55e0319da5169a60acec4a264a35c10862f8abfe2f2cc32c55eb6b0ab4de0efdfa115ea522d6d4d361dea07feae27710e59370b70671d347daddec662182e4c514cbcba8dae1736cf735f29e19b9a42be523d0836d04fa3b15dd57de52f4%22%2C%22key_id%22%3A%2230%22%2C%22sign%22%3A%22551bc5f4%22%7D; Hm_lpvt_4aadd610dfd2f5972f1efee2653a2bc5=1700038278; RT="z=1&dm=baidu.com&si=bd56d547-8a2c-433d-9eee-70f64ccf646a&ss=lozishrc&sl=9&tt=c2s&bcn=https%3A%2F%2Ffclog.baidu.com%2Flog%2Fweirwood%3Ftype%3Dperf&ld=6z26"',
  56. 'Referer': 'https://haokan.baidu.com/author/1774716548084013',
  57. 'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/119.0.0.0 Safari/537.36'
  58. }
  59. response = requests.request("GET", url, headers=headers, params=params)
  60. result = response.json()
  61. print(json.dumps(result, ensure_ascii=False, indent=4))
  62. # 获取小视频列表
  63. def get_tiny_video_list(self):
  64. url = "https://haokan.baidu.com/web/author/listall"
  65. params = {
  66. "app_id": self.account_id,
  67. "ctime": "",
  68. "video_type": "haokan|tabhubVideo",
  69. "rn": 20
  70. }
  71. headers = {
  72. 'Accept': '*/*',
  73. 'Accept-Language': 'en,zh-CN;q=0.9,zh;q=0.8',
  74. 'Cache-Control': 'no-cache',
  75. 'Connection': 'keep-alive',
  76. 'Content-Type': 'application/x-www-form-urlencoded',
  77. 'Cookie': 'BIDUPSID=504D4A3A8D0584CA8C3BE27ACFED5323; PSTM=1695297510; BAIDUID=504D4A3A8D0584CA7398158209FA507F:FG=1; BAIDUID_BFESS=504D4A3A8D0584CA7398158209FA507F:FG=1; H_WISE_SIDS=213352_214793_110085_244721_236312_265883_265985_269905_271172_270102_234295_234207_272282_263618_272473_260335_273141_273244_273397_273481_275098_275007_275853_276196_275170_271562_253022_275870_277354_251972_277631_277642_277635_277611_275732_276665_275209_277554_259642_278057_278166_278163_278300_274784_275167_278263_272560_278573_278575_277542_278790_278388_256739_278920_279021_279045_278237_279267_276573_279367_279385_278392_274947_276269_278946_279086_279610_279605_279680_276983_279877_279307_279695_279945_279703_279975_279998_278249_278213_280132_280209_277699_280161_280227_274286_280405_280368_278674_280485_280541_270366_278414_276929_275856_280614_256223_280488_280636_276438_280560_277759_279896_280768_280809_279850_280771_280107_280583; H_WISE_SIDS_BFESS=213352_214793_110085_244721_236312_265883_265985_269905_271172_270102_234295_234207_272282_263618_272473_260335_273141_273244_273397_273481_275098_275007_275853_276196_275170_271562_253022_275870_277354_251972_277631_277642_277635_277611_275732_276665_275209_277554_259642_278057_278166_278163_278300_274784_275167_278263_272560_278573_278575_277542_278790_278388_256739_278920_279021_279045_278237_279267_276573_279367_279385_278392_274947_276269_278946_279086_279610_279605_279680_276983_279877_279307_279695_279945_279703_279975_279998_278249_278213_280132_280209_277699_280161_280227_274286_280405_280368_278674_280485_280541_270366_278414_276929_275856_280614_256223_280488_280636_276438_280560_277759_279896_280768_280809_279850_280771_280107_280583; sensorsdata2015jssdkcross=%7B%22distinct_id%22%3A%2218b98064c148fe-08a95b8d70a5fe-17525634-1901520-18b98064c151479%22%2C%22first_id%22%3A%22%22%2C%22props%22%3A%7B%22%24latest_traffic_source_type%22%3A%22%E7%9B%B4%E6%8E%A5%E6%B5%81%E9%87%8F%22%2C%22%24latest_search_keyword%22%3A%22%E6%9C%AA%E5%8F%96%E5%88%B0%E5%80%BC_%E7%9B%B4%E6%8E%A5%E6%89%93%E5%BC%80%22%2C%22%24latest_referrer%22%3A%22%22%7D%2C%22%24device_id%22%3A%2218b98064c148fe-08a95b8d70a5fe-17525634-1901520-18b98064c151479%22%7D; H_PS_PSSID=39624_39663_39684_39690_39676_39678_39713; BDORZ=B490B5EBF6F3CD402E515D22BCDA1598; hkpcSearch=%u674E%u6709%u8D22; BA_HECTOR=0h240k018l2ka0a000a00g0g1il6sn21q; ZFY=PnfJdvQrpMNOIoZw1LsOKMDW8:BWcrmDvtL60fANYxmQ:C; Hm_lvt_4aadd610dfd2f5972f1efee2653a2bc5=1699950106,1700038092; PC_TAB_LOG=video_details_page; COMMON_LID=c414c76cb1b11dfb04b7062a5ae09ce2; BDRCVFR[X_XKQks0S63]=mk3SLVN4HKm; ab_sr=1.0.1_ODM2M2M4NzY2MWE3Yjg0MGQ4NDk2YTQ4ZTRlMWVlYjdiY2JmMzQ5ZjU1MjAxODUxZTQ0NTg4YjJjNzNmYTU2MzZiMjI2Y2EwZTU2OGIwYjdmMDc3NmRhMGJjODZkZmIyN2U0YWFjMjUzZWEwNTRlZWQ1N2U0MzkxY2YwMzk4Zjk1N2NiYWM1OGZlN2M0NWU4ZWJiZjFmNWE5YWU3YjFmMA==; reptileData=%7B%22data%22%3A%22636c55e0319da5169a60acec4a264a35c10862f8abfe2f2cc32c55eb6b0ab4de0efdfa115ea522d6d4d361dea07feae27710e59370b70671d347daddec6621825f6963cc8f86c5fee1d0664c82edf0ae5c838cf8bde5188e6a7757f1998a7c48%22%2C%22key_id%22%3A%2230%22%2C%22sign%22%3A%22f302bd06%22%7D; Hm_lpvt_4aadd610dfd2f5972f1efee2653a2bc5=1700046227; RT="z=1&dm=baidu.com&si=bd56d547-8a2c-433d-9eee-70f64ccf646a&ss=loznmnju&sl=1&tt=1w3&bcn=https%3A%2F%2Ffclog.baidu.com%2Flog%2Fweirwood%3Ftype%3Dperf&ld=2oq"',
  78. 'Referer': 'https://haokan.baidu.com/author/1702511677416581',
  79. 'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/119.0.0.0 Safari/537.36'
  80. }
  81. response = requests.request("GET", url, headers=headers, params=params)
  82. result = response.json()
  83. print(json.dumps(result, ensure_ascii=False, indent=4))
  84. # 处理视频列表(建议可以公共化)
  85. def process_video_list(self, result):
  86. if result['errmsg'] == "成功":
  87. video_list = result['data']['results']
  88. for index, video_obj in enumerate(video_list):
  89. try:
  90. AliyunLogger.logging(
  91. code="1001",
  92. platform=self.platform,
  93. mode=self.mode,
  94. env=self.env,
  95. message="扫描到一条视频",
  96. data=video_obj
  97. )
  98. self.get_video_info(video_obj)
  99. except Exception as e:
  100. AliyunLogger.logging(
  101. code="3000",
  102. platform=self.platform,
  103. mode=self.mode,
  104. env=self.env,
  105. message="抓取单条视频异常,报错是:{}".format(e)
  106. )
  107. else:
  108. AliyunLogger.logging(
  109. code="3000",
  110. platform=self.platform,
  111. mode=self.mode,
  112. env=self.env,
  113. message="请求视频链接列表失败,需要 review 代码验证"
  114. )
  115. # 处理单条视频信息
  116. def get_video_info(self, video_obj):
  117. url = "https://haokan.baidu.com/v?vid={}&collection_id=".format(video_obj['content']['vid'])
  118. header = {
  119. "User-Agent": FakeUserAgent().random()
  120. }
  121. response_text = requests.get(url, headers=header).text
  122. encrypted_data = json.loads(
  123. re.search(r'window\.__PRELOADED_STATE__\s*=\s*(.*?);', response_text).group(1).strip())
  124. encrypted_video_obj = encrypted_data['encrptedVideoMeta']
  125. d_obj = json.loads(self.decrypt(encrypted_video_obj))
  126. AliyunLogger.logging(
  127. code="1001",
  128. platform=self.platform,
  129. mode=self.mode,
  130. env=self.env,
  131. data=d_obj,
  132. message="扫描到一条视频"
  133. )
  134. trace_id = self.platform + str(uuid.uuid1())
  135. item = VideoItem()
  136. item.add_video_info("video_id", d_obj['id'])
  137. item.add_video_info("video_title", d_obj['title'])
  138. item.add_video_info("playcnt", d_obj['playcnt'])
  139. item.add_video_info("publish_time_stamp", d_obj['publish_time'])
  140. item.add_video_info("duration", d_obj['duration'])
  141. item.add_video_info("video_url", d_obj['playurl'])
  142. item.add_video_info("like_cnt", d_obj['like'])
  143. item.add_video_info("comment_cnt", d_obj['comment'])
  144. item.add_video_info("cover_url", video_obj['content']['cover_src'])
  145. # 准备发往 MQ 的消息
  146. mq_obj = item.produce_item()
  147. # 筛选规则的 pipeline
  148. pipeline = PiaoQuanPipeline(
  149. platform=self.platform,
  150. mode=self.mode,
  151. rule_dict=self.rule_dict,
  152. env=self.env,
  153. item=mq_obj,
  154. trace_id=trace_id
  155. )
  156. if pipeline.process_item():
  157. self.mq.send_msg(mq_obj)
  158. AliyunLogger.logging(
  159. code="1002",
  160. platform=self.platform,
  161. mode=self.mode,
  162. env=self.env,
  163. message="成功发送至 ETL",
  164. data=mq_obj,
  165. trace_id=trace_id
  166. )
  167. if __name__ == "__main__":
  168. T = HaoKaoVideoAccount(
  169. platform="baidu",
  170. mode="author",
  171. rule_dict={},
  172. user_dict={"link": 1657075178605219},
  173. env="prod"
  174. )
  175. T.get_tiny_video_list()