Requests-html 我可以获取所有请求的状态代码吗(或 selenium 替代品)
Requests-html can I get status codes of all requests (or selenium alternative)
我有以下代码:
from requests_html import HTMLSession
ses = HTMLSession()
r = ses.get(MYURL) # start a headless chrome browser and load MYURL
r.render(keep_page=True) # This will now 'render' the html page
# which means like in a real browser trigger
# all requests for dependent links.
# like .css, .js, .jpg, .gif
调用 render()
会触发对 Javascript、位图等的大量请求。
有什么办法可以跟踪每个请求的状态代码。
我最感兴趣的是 404
,但 403
和 5xx
错误也可能很有趣。
例如,一个用例是:
• 转到一页或一系列页面
• 然后报告有多少请求失败以及访问了哪些 url。
如果 requests-html 无法做到这一点,但使用 selenium 相当简单,我可以切换到 selenium
附录:丑陋的解决方法 1:
我可以设置日志记录以登录到文件并将日志级别设置为调试。
然后我可以尝试解析 websockets.protocol: 的日志,其中包含类似的字符串
{\"url\":\"https://my.server/example.gif\",\"status\":404,\"statusText\":\"...
问题:
将日志级别 DEBUG 激活到一个文件中似乎激活了其他东西,因为突然加载的调试信息也被记录到 stdout
。
例如:
[I:pyppeteer.launcher] Browser listening on: ws://127.0.0.1:45945/devtools/browser/bc5ce097-e67d-455e-8a59-9a4c213263c1
[D:pyppeteer.connection.Connection] SEND: {"id": 1, "method": "Target.setDiscoverTargets", "params": {"discover": true}}
此外,实时解析它并将其与我在代码中使用的 url 相关联也不是很有趣。
附录:丑陋的解决方案 2:
更糟糕的是关联,但更好的解析和识别 404
s 并且只要控制 http 服务器就可以工作。
用 nginx 解析日志 http 服务器的日志我什至可以用我感兴趣的数据设置一个 csv 格式的自定义记录器。
附录:丑陋的解决方案 3:
使用 python 日志记录(pyppeteer
的专用处理程序和过滤器)我可以拦截描述 pyppeteer.connection.CDPSession
记录器响应的 json 字符串,而无需 stderr
被污染。
过滤器允许我实时检索数据。
这仍然很老套。所以寻找更好的解决方案。
尝试以下内容,看看它是否是您想要的。它严格来说是一个 pyppeteer 版本(而不是 requests_html)并且依赖于未公开的私有变量,因此很容易受到版本更新的破坏。
import asyncio
from pyppeteer import launch
from pyppeteer.network_manager import NetworkManager
def logit(event):
req = event._request
print("{0} - {1}".format(req.url, event._status))
async def main():
browser = await launch({"headless": False})
page = await browser.newPage()
page._networkManager.on(NetworkManager.Events.Response, logit)
await page.goto('https://www.google.com')
await browser.close()
asyncio.get_event_loop().run_until_complete(main())
检查 requests_html 浏览器页面对象的来源似乎被埋得很深——所以获取 NetworkManager 并不是那么简单。如果您真的希望它在 requests_html 内工作,那么 monkeypatch 可能是最简单的方法。这是一个例子:
import asyncio
from requests_html import HTMLSession, TimeoutError, HTML
from pyppeteer.network_manager import NetworkManager
from typing import Optional, Union
def logit(event):
req = event._request
print("{0} - {1}".format(req.url, event._status))
async def _async_render(self, *, url: str, script: str = None, scrolldown, sleep: int, wait: float, reload, content: Optional[str], timeout: Union[float, int], keep_page: bool, cookies: list = [{}]):
""" Handle page creation and js rendering. Internal use for render/arender methods. """
try:
page = await self.browser.newPage()
page._networkManager.on(NetworkManager.Events.Response, logit)
# Wait before rendering the page, to prevent timeouts.
await asyncio.sleep(wait)
if cookies:
for cookie in cookies:
if cookie:
await page.setCookie(cookie)
# Load the given page (GET request, obviously.)
if reload:
await page.goto(url, options={'timeout': int(timeout * 1000)})
else:
await page.goto(f'data:text/html,{self.html}', options={'timeout': int(timeout * 1000)})
result = None
if script:
result = await page.evaluate(script)
if scrolldown:
for _ in range(scrolldown):
await page._keyboard.down('PageDown')
await asyncio.sleep(sleep)
else:
await asyncio.sleep(sleep)
if scrolldown:
await page._keyboard.up('PageDown')
# Return the content of the page, JavaScript evaluated.
content = await page.content()
if not keep_page:
await page.close()
page = None
return content, result, page
except TimeoutError:
await page.close()
page = None
return None
ses = HTMLSession()
r = ses.get('https://www.google.com') # start a headless chrome browser and load MYURL
html = r.html
html._async_render = _async_render.__get__(html, HTML)
html.render()
我有以下代码:
from requests_html import HTMLSession
ses = HTMLSession()
r = ses.get(MYURL) # start a headless chrome browser and load MYURL
r.render(keep_page=True) # This will now 'render' the html page
# which means like in a real browser trigger
# all requests for dependent links.
# like .css, .js, .jpg, .gif
调用 render()
会触发对 Javascript、位图等的大量请求。
有什么办法可以跟踪每个请求的状态代码。
我最感兴趣的是 404
,但 403
和 5xx
错误也可能很有趣。
例如,一个用例是:
• 转到一页或一系列页面
• 然后报告有多少请求失败以及访问了哪些 url。
如果 requests-html 无法做到这一点,但使用 selenium 相当简单,我可以切换到 selenium
附录:丑陋的解决方法 1:
我可以设置日志记录以登录到文件并将日志级别设置为调试。
然后我可以尝试解析 websockets.protocol: 的日志,其中包含类似的字符串
{\"url\":\"https://my.server/example.gif\",\"status\":404,\"statusText\":\"...
问题:
将日志级别 DEBUG 激活到一个文件中似乎激活了其他东西,因为突然加载的调试信息也被记录到 stdout
。
例如:
[I:pyppeteer.launcher] Browser listening on: ws://127.0.0.1:45945/devtools/browser/bc5ce097-e67d-455e-8a59-9a4c213263c1
[D:pyppeteer.connection.Connection] SEND: {"id": 1, "method": "Target.setDiscoverTargets", "params": {"discover": true}}
此外,实时解析它并将其与我在代码中使用的 url 相关联也不是很有趣。
附录:丑陋的解决方案 2:
更糟糕的是关联,但更好的解析和识别 404
s 并且只要控制 http 服务器就可以工作。
用 nginx 解析日志 http 服务器的日志我什至可以用我感兴趣的数据设置一个 csv 格式的自定义记录器。
附录:丑陋的解决方案 3:
使用 python 日志记录(pyppeteer
的专用处理程序和过滤器)我可以拦截描述 pyppeteer.connection.CDPSession
记录器响应的 json 字符串,而无需 stderr
被污染。
过滤器允许我实时检索数据。
这仍然很老套。所以寻找更好的解决方案。
尝试以下内容,看看它是否是您想要的。它严格来说是一个 pyppeteer 版本(而不是 requests_html)并且依赖于未公开的私有变量,因此很容易受到版本更新的破坏。
import asyncio
from pyppeteer import launch
from pyppeteer.network_manager import NetworkManager
def logit(event):
req = event._request
print("{0} - {1}".format(req.url, event._status))
async def main():
browser = await launch({"headless": False})
page = await browser.newPage()
page._networkManager.on(NetworkManager.Events.Response, logit)
await page.goto('https://www.google.com')
await browser.close()
asyncio.get_event_loop().run_until_complete(main())
检查 requests_html 浏览器页面对象的来源似乎被埋得很深——所以获取 NetworkManager 并不是那么简单。如果您真的希望它在 requests_html 内工作,那么 monkeypatch 可能是最简单的方法。这是一个例子:
import asyncio
from requests_html import HTMLSession, TimeoutError, HTML
from pyppeteer.network_manager import NetworkManager
from typing import Optional, Union
def logit(event):
req = event._request
print("{0} - {1}".format(req.url, event._status))
async def _async_render(self, *, url: str, script: str = None, scrolldown, sleep: int, wait: float, reload, content: Optional[str], timeout: Union[float, int], keep_page: bool, cookies: list = [{}]):
""" Handle page creation and js rendering. Internal use for render/arender methods. """
try:
page = await self.browser.newPage()
page._networkManager.on(NetworkManager.Events.Response, logit)
# Wait before rendering the page, to prevent timeouts.
await asyncio.sleep(wait)
if cookies:
for cookie in cookies:
if cookie:
await page.setCookie(cookie)
# Load the given page (GET request, obviously.)
if reload:
await page.goto(url, options={'timeout': int(timeout * 1000)})
else:
await page.goto(f'data:text/html,{self.html}', options={'timeout': int(timeout * 1000)})
result = None
if script:
result = await page.evaluate(script)
if scrolldown:
for _ in range(scrolldown):
await page._keyboard.down('PageDown')
await asyncio.sleep(sleep)
else:
await asyncio.sleep(sleep)
if scrolldown:
await page._keyboard.up('PageDown')
# Return the content of the page, JavaScript evaluated.
content = await page.content()
if not keep_page:
await page.close()
page = None
return content, result, page
except TimeoutError:
await page.close()
page = None
return None
ses = HTMLSession()
r = ses.get('https://www.google.com') # start a headless chrome browser and load MYURL
html = r.html
html._async_render = _async_render.__get__(html, HTML)
html.render()