使用“Requests-HTML”库获取交易价格时遇到问题

Posted

技术标签:

【中文标题】使用“Requests-HTML”库获取交易价格时遇到问题【英文标题】:Trouble getting the trade-price using "Requests-HTML" library 【发布时间】:2018-08-07 23:54:59 【问题描述】:

我在 python 中编写了一个脚本,以从 javascript 呈现的网页中获取最后一笔交易的价格。如果我选择使用selenium,我可以获得内容。我的目标是不使用任何浏览器模拟器,如selenium 或其他东西,因为最新版本的Requests-html 应该能够解析javascript 加密内容。但是,我无法成功。当我运行脚本时,我收到以下错误。对此的任何帮助将不胜感激。

网站地址:webpage_link

我尝试过的脚本:

import requests_html

with requests_html.HTMLSession() as session:
    r = session.get('https://www.gdax.com/trade/LTC-EUR')
    js = r.html.render()
    item = js.find('.MarketInfo_market-num_1lAXs',first=True).text
    print(item)

这是完整的回溯:

Exception in callback NavigatorWatcher.waitForNavigation.<locals>.watchdog_cb(<Task finishe...> result=None>) at C:\Users\ar\AppData\Local\Programs\Python\Python36-32\lib\site-packages\pyppeteer\navigator_watcher.py:49
handle: <Handle NavigatorWatcher.waitForNavigation.<locals>.watchdog_cb(<Task finishe...> result=None>) at C:\Users\ar\AppData\Local\Programs\Python\Python36-32\lib\site-packages\pyppeteer\navigator_watcher.py:49>
Traceback (most recent call last):
  File "C:\Users\ar\AppData\Local\Programs\Python\Python36-32\lib\asyncio\events.py", line 145, in _run
    self._callback(*self._args)
  File "C:\Users\ar\AppData\Local\Programs\Python\Python36-32\lib\site-packages\pyppeteer\navigator_watcher.py", line 52, in watchdog_cb
    self._timeout)
  File "C:\Users\ar\AppData\Local\Programs\Python\Python36-32\lib\site-packages\pyppeteer\navigator_watcher.py", line 40, in _raise_error
    raise error
concurrent.futures._base.TimeoutError: Navigation Timeout Exceeded: 3000 ms exceeded
Traceback (most recent call last):
  File "C:\Users\ar\AppData\Local\Programs\Python\Python36-32\experiment.py", line 6, in <module>
    item = js.find('.MarketInfo_market-num_1lAXs',first=True).text
AttributeError: 'NoneType' object has no attribute 'find'
Error in atexit._run_exitfuncs:
Traceback (most recent call last):
  File "C:\Users\ar\AppData\Local\Programs\Python\Python36-32\lib\shutil.py", line 387, in _rmtree_unsafe
    os.unlink(fullname)
PermissionError: [WinError 5] Access is denied: 'C:\\Users\\ar\\.pyppeteer\\.dev_profile\\tmp1gng46sw\\CrashpadMetrics-active.pma'

我想要的价格显示在页面顶部,可以像 177.59 EUR Last trade price 这样看到。我希望得到177.59 或任何当前价格。

【问题讨论】:

会不会是因为render函数没有返回结果对象,但结果对象仍然是r?如果你这样做r.html.search(...)会发生什么? 没有改善。我尝试使用.search() 并收到此错误AttributeError: 'NoneType' object has no attribute 'search 【参考方案1】:

您有几个错误。第一个是“导航”超时,表明页面没有完成渲染:

Exception in callback NavigatorWatcher.waitForNavigation.<locals>.watchdog_cb(<Task finishe...> result=None>) at C:\Users\ar\AppData\Local\Programs\Python\Python36-32\lib\site-packages\pyppeteer\navigator_watcher.py:49
handle: <Handle NavigatorWatcher.waitForNavigation.<locals>.watchdog_cb(<Task finishe...> result=None>) at C:\Users\ar\AppData\Local\Programs\Python\Python36-32\lib\site-packages\pyppeteer\navigator_watcher.py:49>
Traceback (most recent call last):
  File "C:\Users\ar\AppData\Local\Programs\Python\Python36-32\lib\asyncio\events.py", line 145, in _run
    self._callback(*self._args)
  File "C:\Users\ar\AppData\Local\Programs\Python\Python36-32\lib\site-packages\pyppeteer\navigator_watcher.py", line 52, in watchdog_cb
    self._timeout)
  File "C:\Users\ar\AppData\Local\Programs\Python\Python36-32\lib\site-packages\pyppeteer\navigator_watcher.py", line 40, in _raise_error
    raise error
concurrent.futures._base.TimeoutError: Navigation Timeout Exceeded: 3000 ms exceeded

此回溯未在主线程中引发,您的代码并未因此中止。您的页面可能不完整;您可能希望设置更长的超时时间或引入睡眠周期,以便浏览器有时间处理 AJAX 响应。

接下来,response.html.render() 元素返回None。它将 HTML 加载到无头 Chromium 浏览器中,将 JavaScript 渲染留给该浏览器,然后将页面 HTML 复制回 response.html 数据结构就地,不需要返回任何内容。所以js 设置为None,而不是新的HTML 实例,这会导致您的下一个回溯。

使用现有的 response.html 对象进行搜索,渲染后:

r.html.render()
item = r.html.find('.MarketInfo_market-num_1lAXs', first=True)

很可能没有这样的 CSS 类,因为在通过 AJAX 加载 JSON 数据之后,在每个页面渲染中生成最后 5 个字符。这使得很难使用 CSS 找到有问题的元素。

此外,我发现如果没有睡眠周期,浏览器就没有时间获取 AJAX 资源并呈现您想要加载的信息。在复制回 HTML 之前,给它 10 秒的 sleep 做一些工作。如果您看到网络超时,请设置更长的超时时间(默认为 8 秒):

r.html.render(timeout=10, sleep=10)

您也可以将timeout 设置为0,以消除超时并无限期地等待页面加载。

希望a future API update 也为wait for network activity to cease 提供功能。

您可以使用included parse library 来查找匹配的 CSS 类:

# search for CSS suffixes
suffixes = [r[0] for r in r.html.search_all('MarketInfo_market-num_:w')]
for suffix in suffixes:
    # for each suffix, find all matching elements with that class
    items = r.html.find('.MarketInfo_market-num_'.format(suffix))
    for item in items:
        print(item.text)

现在我们得到了输出:

169.81 EUR
+
1.01 %
18,420 LTC
169.81 EUR
+
1.01 %
18,420 LTC
169.81 EUR
+
1.01 %
18,420 LTC
169.81 EUR
+
1.01 %
18,420 LTC

您最后的回溯显示无法清理 Chromium 用户数据路径。底层 Pyppeteer library 使用临时用户数据路径配置无头 Chromium 浏览器,在您的情况下,该目录包含一些仍然锁定的资源。您可以忽略该错误,但您可能希望稍后尝试删除 .pyppeteer 文件夹中的所有剩余文件。

【讨论】:

您在延迟和修复 css 选择器方面是非常正确的。上述脚本中使用的选择器有问题,因为它是动态生成的。我试过[class^='MarketInfo_market-num_']r.html.render(sleep=10)。我现在得到结果。错误仍然存​​在以及预期的结果。有什么办法可以消除错误? @SIM:如果你看到TimeoutErrors,渲染时设置一个更大的timeout=值。或者将其设置为 0 以完全消除超时。 r.html.render(timeout=10, sleep=10) 在我的情况下,它会启动一个新会话并再次解析登录页面,知道为什么吗? @Pritish:不,对不起。【参考方案2】:

您需要它来通过 Requests-HTML 吗?在您发布的那天,repo 已经 4 天了,在过去的 3 天里已经有 50 次提交。它在一段时间内不会完全稳定。

请看这里: https://github.com/kennethreitz/requests-html/graphs/commit-activity

OTOH,有一个用于 gdax 的 API。

https://docs.gdax.com/#market-data

现在,如果您不喜欢使用 Py3,GDAX 网站上列出了一个 python 客户端。预先我会提到它是非官方客户;但是,如果您使用它,您将能够快速轻松地从官方 GDAX api 获得响应。

https://github.com/danpaquin/gdax-python

【讨论】:

@shayan:然后选择一个目前不会引起问题的网站。从外观上看,页面只是未能加载额外的资源。【参考方案3】:

如果您想通过运行 Selenium 网页抓取来使用其他方式

from selenium import webdriver
from selenium.webdriver.common.keys import Keys 
from selenium.common.exceptions import TimeoutException


chrome_path = r"C:\Users\Mike\Desktop\chromedriver.exe"    

driver = webdriver.Chrome(chrome_path)

driver.get("https://www.gdax.com/trade/LTC-EUR")

item = driver.find_element_by_xpath('''//span[@class='MarketInfo_market-num_1lAXs']''') 
item = item.text
print item
driver.close()

结果:1​​77.60 欧元

【讨论】:

以上是关于使用“Requests-HTML”库获取交易价格时遇到问题的主要内容,如果未能解决你的问题,请参考以下文章

Python技能树共建requests-html库初识

Python技能树共建requests-html库初识

Python网页解析库:用requests-html爬取网页

爬虫最新的库requests-html库总结

requests-html库初识 + 无资料解BUG之 I/O error : encoder error,Python爬虫第30例

requests-html库初识 + 无资料解BUG之 I/O error : encoder error,Python爬虫第30例