无法使用“请求-HTML”库获取交易价格

时间:2018-02-28 07:12:03

标签: python python-3.x web-scraping python-requests python-requests-html

我在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或当前的价格。

3 个答案:

答案 0 :(得分:12)

您有几个错误。第一个是导航&#39;超时,显示页面未完成呈现:

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文件夹中的所有剩余文件。

答案 1 :(得分:2)

您是否需要通过Requests-HTML?在您发布的那天,回购邮件已经过了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

答案 2 :(得分:1)

如果您想通过运行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 EUR