Python 从 URL 抓取 YouTube 标题的速度太慢 - html-render

问题描述

嗨,我有带有 youtube url 列表的 excel 文件,我正在尝试获取它们的标题,因为它是 1000 个 url 的完整列表和 3 个 excel 文件,我尝试使用 python 但它变得太慢了,因为我不得不放置 sleep 命令在 html 渲染代码是这样的:

 import xlrd
import time
from bs4 import BeautifulSoup
import requests
from xlutils.copy import copy
from requests_html import HTMLSession



loc = ("testt.xls")

wb = xlrd.open_workbook(loc)
sheet = wb.sheet_by_index(0)
wb2 = copy(wb)
sheet.cell_value(0,0)

for i in range(3,sheet.nrows):


    ytlink = (sheet.cell_value(i,0))
    session = HTMLSession()
    response = session.get(ytlink)
    response.html.render(sleep=3)
    print(sheet.cell_value(i,0))
    print(ytlink)
    element = BeautifulSoup(response.html.html,"lxml")
    media = element.select_one('#container > h1').text
    print(media)
    s2 = wb2.get_sheet(0)
    s2.write(i,media)
    wb2.save("testt.xls")    

我的意思是无论如何都可以让它更快,我尝试了硒,但我猜它更慢。和这个 html.render 我似乎需要使用“睡眠”计时器,否则它会给我错误我尝试较低的睡眠值但它在较低的睡眠值一段时间后出现错误任何帮助请谢谢:)

ps:我放的打印只是为了检查输出,对使用不重要。

解决方法

使用您当前的方法/Selenium,您正在呈现实际的网页,而您不需要这样做。我建议使用一个 Python 库来为你处理它。以下是 YoutubeDL 的示例:

with YoutubeDL() as ydl:
    title = ydl.extract_info("https://www.youtube.com/watch?v=jNQXAC9IVRw",download=False).get("title",None)
    print(title)

请注意,在 YouTube 施加的速率限制下,处理 1000 个这样的请求仍然会很慢。如果您打算在未来处理数千个s 请求,我建议您查看 getting an API key

,

你可以像这样使用 async requests-html 在不到一分钟的时间内完成 1000 个请求:

import random
from time import perf_counter
from requests_html import AsyncHTMLSession

urls = ['https://www.youtube.com/watch?v=z9eoubnO-pE'] * 1000

asession = AsyncHTMLSession()
start = perf_counter()

async def fetch(url):
    r = await asession.get(url,cookies={'CONSENT': 'YES+cb.20210328-17-p0.en-GB+FX+{}'.format(random.randint(100,999))})
    return r

all_responses = asession.run(*[lambda url=url: fetch(url) for url in urls])
all_titles = [r.html.find('title',first=True).text for r in all_responses]

print(all_titles)
print(perf_counter() - start)

在我的笔记本电脑上 55 秒内完成。

请注意,您需要将 cookies={'CONSENT': 'YES+cb.20210328-17-p0.en-GB+FX+{}'.format(random.randint(100,999))} 传递给请求以避免 this issue