问题是youtube的搜索API非常有限,所以我只能用webscraping来抓取搜索结果页面,到目前为止,我试着用seleunm来加载页面并获取html,但是启动时会有相当大的延迟。
如果没有Javascript,youtube搜索结果页面将无法正确生成,所以我不能只运行URL上的get请求。
是否有其他方法可以获得呈现的搜索结果页面?
我现在的代码
def search(self, query):
try:
self.driver.get('https://www.youtube.com/results?search_query={}'.format(str(query)))
self.wait.until(self.visible((By.ID, "video-title")))
elements=self.driver.find_elements(By.XPATH,"//*[@id=\"video-title\"]")
results = []
for element in elements:
results.append([element.text, element.get_attribute('href')])
return results
except:
return []
这是在程序关闭之前重用同一seleunm示例的类的一部分
溶液
import requests
def search(self, query):
re = requests.get('https://www.youtube.com/results?search_query={}'.format(str(query).replace(' ', '+')))
index = 1
j = 0
result = []
while j <= 40: #results are located at every 4 videoId tag
newindex = re.text.find('"videoId":"', index)
videonameindex = re.text.find('{"text"', newindex)
index = newindex +1
if j%4 == 0:
videoname = re.text[videonameindex+8:videonameindex+100]
name = videoname.split('}],')[0].replace('"','')
videoId = re.text[newindex:newindex+30].split(':')[1].split(',')[0].replace('"','')
# make sure the video ID is valid
if len(videoId) != 11:
continue
url = f'https://www.youtube.com/watch?v={videoId}'
result.append([name, url])
j += 1
self.conn.commit()
return result
代码有点长,但现在不再需要等待selenium加载,也不需要等待javascript完成执行
感谢@本杰明· lucene
3条答案
按热度按时间64jmpszr1#
如果你进入
curl https://www.youtube.com/results?search_query=test
,你会发现你要找的结果数据是JavaScript变量ytInitialData
的一部分。我建议你只获取这个HTML文件并解析它的JavaScript变量ytInitialData
。这样你就不需要使用任何JavaScript解释器,比如Selenium,因为它不是必需的,所以速度特别慢。注意:我正在使用这个方法将an open-source alternative开发为YouTube Data API v3。顺便说一句,我有一个类似于您正在寻找的端点。
kkbh8khc2#
使用Selenium的最快方法是使用“渴望”页面加载策略并等待选择器。
但根据我的经验,切换到剧作家(异步)可能会快2倍左右
wdebmtf23#
要使用Selenium从完全渲染的 YouTube 搜索结果页面上的视频标题中提取
href
属性,一个巨大的改进而不是最好的方法是为visibility_of_all_elements_located()引入WebDriverWait,并使用List Comprehension,您可以使用以下解决方案:注意:您必须添加以下导入: