刮取渲染的javascript网页

时间:2017-08-04 20:37:02

标签: javascript python web-scraping

我正在尝试构建一个简短的Python程序,它提取Pewdiepie的订阅者数量,这些订阅者每秒都会在socialblade上更新,以便在终端中显示它。我希望这个数据像每30秒一样。

我已经尝试过使用PyQt,但速度很慢,我已经转向dryscrape,速度稍微快一点,但不能像我想要的那样工作。我刚刚找到Invader并编写了一些仍然存在同样问题的短代码:返回的数字是执行页面上Javascript之前的代码

from invader import Invader

url = 'https://socialblade.com/youtube/user/pewdiepie/realtime'
invader = Invader(url, js=True)

subscribers = invader.take(['#rawCount', 'text'])
print(subscribers.text)

我知道这些数据可以通过site's API访问,但并不总是有效,有时它只是重定向到this

有没有办法在页面上的Javascript修改计数器之后获得此数字而不是之前?哪种方法对你来说最好?提取它:

  • 来自原始页面,它始终返回相同数字的小时数?
  • 来自API的页面,如果在代码中没有使用cookie并且经过一段时间后会出现错误?

感谢您的建议!

2 个答案:

答案 0 :(得分:0)

我已经在dryscrape取得了成功,如下文所述。

Web-scraping JavaScript page with Python

答案 1 :(得分:0)

如果您要抓取一个网页,其中部分网页是通过javascript加载的,则非常需要使用真正的浏览器。

在python中,可以通过pyppeteer实现:

import asyncio
from pyppeteer import launch

async def main():
    browser = await launch(headless=False)
    page = await browser.newPage()
    await page.goto('https://socialblade.com/youtube/user/pewdiepie/realtime',{
        'waitUntil': 'networkidle0'
    })
    count = int(await page.Jeval('#rawCount', 'e => e.innerText'))
    print(count)

asyncio.get_event_loop().run_until_complete(main())

注意:看来您上面提到的网站似乎不再经常更新订阅者人数(即使使用JavaScript)。参见:https://socialblade.com/blog/abbreviated-subscriber-counts-on-youtube/

为了获得最大的成功和可靠性,您可能需要设置用户代理({{1}中的page.setUserAgent)并保持最新状态并使用代理< / strong>(因此您的IP不会被禁止)。这可能是很多工作。

使用像Scraper's Proxy这样可以为您处理服务的服务可能会更容易,更便宜(在时间上,而不是购买大量代理)。它支持使用真实的浏览器,并在JavaScript运行后返回结果html,并通过大型代理网络路由我们的所有请求,因此您可以发送很多请求而不会被IP禁止。

以下是使用Scraper的Proxy API直接从YouTube获取计数的示例:

pyppeteer

我知道这有点晚了,但我希望这会有所帮助