a5.gif

keoki

GF  2021-11-27 21:32
(一些脚本:https://bbs.imoutolove.me/read.php?tid=1353704)

cb站的录播站 recurbate 的反爬措施和绕过手段

相关帖子:

https://bbs.south-plus.org/read.php?tid-1142421-keyword-recurbate.html

https://bbs.south-plus.org/read.php?tid-1189165-keyword-recurbate.html


recurbate 好象是最全最新的 chaturbate 录播站了吧, 看样子是毛子开的 (网站会请求 Yandex.Metrica 的广告文件),会员很贵,20刀一个月。

recurbate.com 域名套了 cloudflare CDN, 媒体文件服务器地址在欧洲国家,比如荷兰和德国。

网站对游客的限制是同时基于 ip 和 cookies, 每个 ip 每天只能请求一个视频文件的地址。



注册免费帐号现在每天限制是一个视频都不能看,所以还不如游客状态。

游客状态下,打开一个视频,点击播放按钮。 浏览器会尝试请求这个地址,"/api/get.php?video=" + id + "&token=" + token , 如果服务器判断你是游客而且 ip 今日已经请求过了,会返回 shall_signin, 然后页面会跳转到登录页面 “/signin?url=”。

如果请求成功视频文件地址会在返回的请求数据 data 里,文件地址大概长这样:

复制代码
  1. https://f15.mediafront.xyz/micu_ko/2021-11-16,16-51.mp4?md5=aYserSak4jkon6nsDbgJaw&expires=1638002800&origin=105&mid=9ce06be3-5dec-45f9-946d-b3e1ca2ecaf5&akey=&p=2000


expires=1638002800 这个是时间戳,值是请求那一刻的时间, mid 是 recurbate.com 域名的某一个 cookie 键值,这个值应该对应了你的 ip 地址,md5=aYserSak4jkon6nsDbgJaw 应该是某个防止伪造的加密值, 估计只有服务器才知道怎么生成。

上面的文件地址是有时效的,10分钟以后这个地址就会返回 410 gone。 这个地址也只有你的 ip 地址才能够请求, 如果你用别的 ip 去请求 他会返回 403 forbidden。

所以你唯一能做的就是找一台网速快的机器, 每天请求一次, 在 10 分钟之内把这个文件下载完。 或者找一个能保证网速高而且稳定的机场,不停的切换节点清空 cookies, 文件服务器在欧洲,如果你下载的文件有 6g 大小, 那你要保证你的下载速度有 10M/s 才行。 而且机场的流量还必须充足,因为可能遇到下到快要完成但是超时的情况需要重新下载。


我的解决方案是写一个脚本,然后在美国的 vps 上运行,获取文件地址后下载, 如果你的机子还过得去, 那么请求欧洲地区的服务器网速应该还行还行, 10分钟下载一个视频没什么问题,下载好后然后在拉回本地。 因为手里有好几台 vps 放着吃灰,正好可以用上。

下面贴几个最近在看的主播,特别推荐第一个樱花妹,外表清纯可爱,玩跳蛋高潮的时候还会痉挛。






最后贴出下载脚本代码,只需要修改视频 id 号就行了:
复制代码
  1. import requests
  2. import re
  3. import sys
  4. s = requests.Session()
  5. header_data = """Host: recurbate.com
  6. User-Agent: Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:94.0) Gecko/20100101 Firefox/94.0
  7. Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8
  8. Accept-Language: en-US,en;q=0.5
  9. Connection: keep-alive
  10. Upgrade-Insecure-Requests: 1
  11. Sec-Fetch-Dest: document
  12. Sec-Fetch-Mode: navigate
  13. Sec-Fetch-Site: none"""
  14. lst2 = header_data.split("\n")
  15. lst_of_lst2 = [lst.split(": ") for lst in lst2]
  16. HEADERS = {lst[0]: lst[1] for lst in lst_of_lst2}
  17. def get_api_token(video_id):
  18.     r = s.get(
  19.         f"https://recurbate.com/play.php?video={video_id}", headers=HEADERS
  20.     )
  21.     r.encoding = r.apparent_encoding
  22.     token = re.findall(r'data-token="(.*?)"', r.text)[0]
  23.     print(token)
  24.     return token
  25. def get_src(token):
  26.     resp = s.get(
  27.         f"https://recurbate.com/api/get.php?video={video_id}&token={token}",
  28.         headers=HEADERS,
  29.     )
  30.     api_resptext = resp.text
  31.     if "source" in api_resptext:
  32.         src = re.findall(r'source src="(.*?)" type="video', api_resptext)[0]
  33.         print("src: ", src)
  34.         return src
  35.     else:
  36.         print("src not got: ", api_resptext)
  37.         return None
  38. def fetch_file(src):
  39.     file_headers_data = """Accept-Encoding: identity;q=1, *;q=0
  40. Accept-Language: en-US,en;q=0.9,zh-CN;q=0.8,zh;q=0.7
  41. Connection: keep-alive
  42. DNT: 1
  43. Host: f18.mediafront.xyz
  44. Range: bytes=0-
  45. sec-ch-ua: " Not A;Brand";v="99", "Chromium";v="96", "Google Chrome";v="96"
  46. sec-ch-ua-mobile: ?0
  47. sec-ch-ua-platform: "Linux"
  48. Sec-Fetch-Dest: video
  49. Sec-Fetch-Mode: no-cors
  50. Sec-Fetch-Site: cross-site
  51. User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.45 Safari/537.36"""
  52.     lst3 = file_headers_data.split("\n")
  53.     lst_of_lst3 = [lst.split(": ") for lst in lst3]
  54.     # print(lst_of_lst2)
  55.     file_headers = {lst[0]: lst[1] for lst in lst_of_lst3}
  56.     response = requests.get(src, headers=file_headers, stream=True)
  57.     print("status code", response.status_code)
  58.     content_length_h = str(response.headers.get("content-length"))
  59.     content_length = int(content_length_h)
  60.     print("file size:", content_length // (1000000), "MB")
  61.     file_path = "./download.mp4"
  62.     with open(file_path, "wb") as file:
  63.         # start downloading
  64.         dl = 0
  65.         for data in response.iter_content(chunk_size=8192):
  66.             dl += len(data)
  67.             file.write(data)
  68.             done = int(50 * dl / content_length)
  69.             sys.stdout.write(
  70.                 "\r[%s%s] %s"
  71.                 % ("=" * done, " " * (50 - done), str(dl // 1000000) + "MB")
  72.             )
  73.             sys.stdout.flush()
  74. video_id = 10654230
  75. token = get_api_token(video_id)
  76. if src := get_src(token):
  77.     fetch_file(src)

none.gif

edward2012751

B1F  2021-11-27 21:44
mark~~
技术大佬拯救世界