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

Python scraping too slow on youtube title from URL - html-render

嗨,我有 excel 个文件和 youtube url 列表,我正在尝试获取它们的标题,因为它是 1000 个 url 的完整列表,其中有 3 个 excel 文件我尝试使用 python 但它变得太慢了,因为我不得不将睡眠命令放在 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, 0, media)
    wb2.save("testt.xls")    

我的意思是有没有办法让它更快我试过 selenium 但我猜它更慢。有了这个 html.render 我似乎需要使用“睡眠”计时器,否则它会给我错误我尝试了较低的睡眠值但是一段时间后它在较低的睡眠值下出现错误任何帮助谢谢:)

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

使用您当前的 method/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)

请注意,执行 1000 个这样的请求,在 YouTube 施加的速率限制下,仍然会很慢。如果您计划将来可能处理数千s 个请求,我建议您查看getting an API key.

您可以使用异步请求在不到一分钟内完成 1000 个请求-html 如下所示:

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))}以避免.