使用requests_html爬取Odysee遇渲染异常,求有效爬取方案
解决Odysee.com搜索数据爬取问题
你遇到的问题核心在于Odysee是单页应用(SPA),搜索结果并非直接嵌入初始HTML,而是通过后端API异步加载的。requests_html的render()方法默认仅渲染初始静态页面,往往还没等API返回数据就获取了内容,所以拿到的都是无关的CSS、JS代码,没有实际搜索结果。
下面提供两种可行的解决方案:
方案1:优化requests_html渲染逻辑
通过延长等待时间、等待目标元素加载完成,确保异步数据已渲染到页面后再获取内容。
修改后的代码示例:
from requests_html import HTMLSession def search(search_terms): session = HTMLSession() url = f"https://odysee.com/$/search?q={search_terms}" headers = {'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36'} try: resp = session.get(url, timeout=10, headers=headers) except Exception as e: return f"连接错误: {str(e)}" # 等待页面渲染,延长等待时间确保API请求完成 resp.html.render(wait=5, sleep=2) # 查找搜索结果元素(需根据Odysee页面结构调整选择器) results = resp.html.find('.video-card') if not results: return "未找到结果或选择器已失效" # 提取标题和链接 search_results = [] for result in results: title_elem = result.find('.video-card__title', first=True) link_elem = result.find('a', first=True) if title_elem and link_elem: search_results.append({ '标题': title_elem.text, '链接': f"https://odysee.com{link_elem.attrs.get('href')}" }) return search_results print(search("clannad"))
注意:页面元素选择器可能随Odysee更新变化,需根据实际页面结构调整.video-card、.video-card__title这类选择器。
方案2:直接调用Odysee搜索API(推荐)
绕过页面渲染,直接请求Odysee后端API获取数据,这是更高效、稳定的方式,无需处理页面渲染问题。
代码示例:
import requests def search_odysee_api(search_terms): url = "https://api.odysee.com/search" headers = { 'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36', 'Content-Type': 'application/json' } payload = { "q": search_terms, "page": 1, "count": 20, "sort": "relevance", "nsfw": False } try: resp = requests.post(url, json=payload, headers=headers, timeout=10) resp.raise_for_status() data = resp.json() except Exception as e: return f"请求错误: {str(e)}" # 提取有效视频数据 search_results = [] if 'result' in data and 'items' in data['result']: for item in data['result']['items']: if item['type'] == 'video': search_results.append({ '标题': item['name'], '链接': f"https://odysee.com/{item['claim_id']}", '播放量': item.get('value', {}).get('release_time', {}).get('views', 0) }) return search_results print(search_odysee_api("clannad"))
API返回的数据结构清晰,可按需提取更多字段(如视频时长、发布时间等),且无需依赖浏览器渲染,速度更快。
内容的提问来源于stack exchange,提问作者Willem van Houten
相关产品推荐
相关产品推荐

