【问题标题】:Scraping a rendered javascript webpage抓取呈现的 javascript 网页
【发布时间】:2018-01-12 21:11:39
【问题描述】:

我正在尝试构建一个简短的 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 时以及经过一定时间后会出现哪些错误?

感谢您的建议!

【问题讨论】:

    标签: javascript python web-scraping


    【解决方案1】:

    如果你想抓取一个网页,它的一部分是通过 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/

    为了获得最佳成功和可靠性,您可能需要设置 用户代理pyppeteer 中的page.setUserAgent)并保持最新状态并使用代理(所以你的IP不会被禁止)。这可能需要大量工作。

    使用像Scraper's Proxy 这样可以为您处理此问题的服务可能更容易、更便宜(及时并且比购买大量代理)。它支持将使用真正的浏览器并在 JavaScript 运行后返回生成的 html,并通过大型代理网络路由我们的所有请求,因此您可以发送大量请求而不会被禁止 ip。

    这是一个使用 Scraper 的代理 API直接从 YouTube 获取计数的示例:

    import requests
    from pyquery import PyQuery
    
    # Send request to API
    url = "https://scrapers-proxy2.p.rapidapi.com/javascript"
    
    params = {
        "click_selector": '#subscriber-count', # (Wait for selector work-around)
        "wait_ajax": 'true',
        "url":"https://www.youtube.com/user/PewDiePie"
    }
    
    headers = {
        'x-rapidapi-host': "scrapers-proxy2.p.rapidapi.com",
        'x-rapidapi-key': "<INSERT YOUR KEY HERE>" # TODO
    }
    
    response = requests.request("GET", url, headers=headers, params=params)
    
    # Query html
    pq = PyQuery(response.text)
    count_text = pq('#subscriber-count').text()
    
    # Extract count from text
    clean_count_text = count_text.split(' ')[0]
    clean_count_text = clean_count_text.replace('K','000')
    clean_count_text = clean_count_text.replace('M','000000')
    count = int(clean_count_text)
    
    print(count)
    

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

    【讨论】:

      猜你喜欢
      • 2019-06-13
      • 2018-06-12
      • 1970-01-01
      • 2018-08-09
      • 2018-04-21
      • 2018-03-02
      • 1970-01-01
      • 1970-01-01
      • 2015-09-09
      相关资源
      最近更新 更多