Python 在 Spyder 中带有请求-html 和异步 'render' 是一场噩梦
Python in Spyder with requests-html and aysnchronous 'render' is a nightmare to figure out
起点是 Spyder IDE。
>Spyder IDE (5.1.0)
>
>The Scientific Python Development Environment | Spyder-IDE.org
>
>Python 3.8.5 64-bit | Qt 5.12.9 | PyQt5 5.12.3 | Linux 5.4.0-81-generic
我想做什么?
抓取一个棘手的博客,似乎 blogspot 更加混淆,但在 Spyder 中,我有时发现我什至无法抓取自己的主页...
import asyncio
from requests_html import AsyncHTMLSession, HTML, HTMLSession
from bs4 import BeautifulSoup as bs
import re
import os, os.path
from pathlib2 import Path
from collections import OrderedDict as Odict
from datetime import datetime, date, timedelta
import pytz
import unicodedata
import sys
# asession = AsyncHTMLSession()
ass = AsyncHTMLSession()
sss = HTMLSession()
url='http://localhost/index.html'
def syncurl(session=None, url=None):
r = session.get(url)
return r
async def asyncurl(session=None, url=None):
r = await session.get(url)
#if r.status_code == 200:
#await r.html.arender()
return r
def gurl(ass, url):
fiz = lambda : asyncurl(ass, url)
foz = ass.run(fiz)
return foz
所以如果我在 Spyder 中 运行 然后执行我得到预期的 'loop already running' 废话。
gurl(ass,url)
Traceback (most recent call last):
File "<ipython-input-2-ebc91fe79d44>", line 1, in <module>
gurl(ass,url)
File "/home/user/PycharmProjects/blogscrape/BlogScraping/asynctest.py", line 38, in gurl
foz = ass.run(fiz)
File "/opt/anaconda3/lib/python3.8/site-packages/requests_html.py", line 774, in run
done, _ = self.loop.run_until_complete(asyncio.wait(tasks))
File "/opt/anaconda3/lib/python3.8/asyncio/base_events.py", line 592, in run_until_complete
self._check_running()
File "/opt/anaconda3/lib/python3.8/asyncio/base_events.py", line 552, in _check_running
raise RuntimeError(f'This event loop is already running : {self._thread_id}')
RuntimeError: This event loop is already running : 139750638774080
我并不想在这里重新发明轮子,我相信很多其他人也有这个问题,但到目前为止我还没有看到一个简洁的答案(除了它是一个 Spyder 错误等)。
我只是想让它在 Spyder 中工作(主要是因为我喜欢玩弄 pandas 来查看结果)。
我想一种方法是 运行 作为独立脚本将结果保存到 pickle 中,然后使用 spyder 重新加载数据框并使用它。但是,嘿,为什么有必要这样做?
主要问题是请求不够明确-html。对于只是试图解决 ..
的原始问题的任何人来说,该错误是非常不透明的
RuntimeError: Cannot use HTMLSession within an existing event loop.
Use AsyncHTMLSession instead.
是的,我已经尝试 Google 这个问题,但他们总是开始谈论 'asyncio' 东西。我正在阅读 'requests-html' 帮助,除此之外的任何内容都高于我的薪资等级(目前为零)。
那么有什么建议吗?
(只有简单的 IC 设计人员可以理解的来自 asyncio 的简单内容)。
谢谢@Daniel,
是的,这似乎确实有效,可以解决上面显示的问题。虽然它不是 100% 完美,因为有时我会收到超时错误,我不确定为什么,但我不再收到超时错误。
只是为了把它全部放在一个地方..安装后,
pip install nest_asyncio
只需将以下内容添加到 python 代码即可。
import nest_asyncio
nest_asyncio.apply()
这足以在 Spyder 中获取代码 运行ning(因为这是原始问题)。
在 'asyncurl' 的代码中添加额外的睡眠/超时允许脚本 运行,尽管速度很慢,所以不要尝试 运行 脚本中调用太多.上述函数修改如下
async def asyncurl(session=None, url=None):
r = await session.get(url)
await asyncio.sleep(5.0)
# if r.status_code == 200:
await r.html.arender(timeout=20000)
return r
起点是 Spyder IDE。
>Spyder IDE (5.1.0)
>
>The Scientific Python Development Environment | Spyder-IDE.org
>
>Python 3.8.5 64-bit | Qt 5.12.9 | PyQt5 5.12.3 | Linux 5.4.0-81-generic
我想做什么? 抓取一个棘手的博客,似乎 blogspot 更加混淆,但在 Spyder 中,我有时发现我什至无法抓取自己的主页...
import asyncio
from requests_html import AsyncHTMLSession, HTML, HTMLSession
from bs4 import BeautifulSoup as bs
import re
import os, os.path
from pathlib2 import Path
from collections import OrderedDict as Odict
from datetime import datetime, date, timedelta
import pytz
import unicodedata
import sys
# asession = AsyncHTMLSession()
ass = AsyncHTMLSession()
sss = HTMLSession()
url='http://localhost/index.html'
def syncurl(session=None, url=None):
r = session.get(url)
return r
async def asyncurl(session=None, url=None):
r = await session.get(url)
#if r.status_code == 200:
#await r.html.arender()
return r
def gurl(ass, url):
fiz = lambda : asyncurl(ass, url)
foz = ass.run(fiz)
return foz
所以如果我在 Spyder 中 运行 然后执行我得到预期的 'loop already running' 废话。
gurl(ass,url)
Traceback (most recent call last):
File "<ipython-input-2-ebc91fe79d44>", line 1, in <module>
gurl(ass,url)
File "/home/user/PycharmProjects/blogscrape/BlogScraping/asynctest.py", line 38, in gurl
foz = ass.run(fiz)
File "/opt/anaconda3/lib/python3.8/site-packages/requests_html.py", line 774, in run
done, _ = self.loop.run_until_complete(asyncio.wait(tasks))
File "/opt/anaconda3/lib/python3.8/asyncio/base_events.py", line 592, in run_until_complete
self._check_running()
File "/opt/anaconda3/lib/python3.8/asyncio/base_events.py", line 552, in _check_running
raise RuntimeError(f'This event loop is already running : {self._thread_id}')
RuntimeError: This event loop is already running : 139750638774080
我并不想在这里重新发明轮子,我相信很多其他人也有这个问题,但到目前为止我还没有看到一个简洁的答案(除了它是一个 Spyder 错误等)。 我只是想让它在 Spyder 中工作(主要是因为我喜欢玩弄 pandas 来查看结果)。 我想一种方法是 运行 作为独立脚本将结果保存到 pickle 中,然后使用 spyder 重新加载数据框并使用它。但是,嘿,为什么有必要这样做?
主要问题是请求不够明确-html。对于只是试图解决 ..
的原始问题的任何人来说,该错误是非常不透明的RuntimeError: Cannot use HTMLSession within an existing event loop. Use AsyncHTMLSession instead.
是的,我已经尝试 Google 这个问题,但他们总是开始谈论 'asyncio' 东西。我正在阅读 'requests-html' 帮助,除此之外的任何内容都高于我的薪资等级(目前为零)。
那么有什么建议吗? (只有简单的 IC 设计人员可以理解的来自 asyncio 的简单内容)。
谢谢@Daniel, 是的,这似乎确实有效,可以解决上面显示的问题。虽然它不是 100% 完美,因为有时我会收到超时错误,我不确定为什么,但我不再收到超时错误。
只是为了把它全部放在一个地方..安装后,
pip install nest_asyncio
只需将以下内容添加到 python 代码即可。
import nest_asyncio
nest_asyncio.apply()
这足以在 Spyder 中获取代码 运行ning(因为这是原始问题)。
在 'asyncurl' 的代码中添加额外的睡眠/超时允许脚本 运行,尽管速度很慢,所以不要尝试 运行 脚本中调用太多.上述函数修改如下
async def asyncurl(session=None, url=None):
r = await session.get(url)
await asyncio.sleep(5.0)
# if r.status_code == 200:
await r.html.arender(timeout=20000)
return r