[英]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
错误也可能很有趣。
例如,一个用例是:
• Go 到一个页面或一系列页面
• 然后报告有多少请求失败以及访问了哪些网址。
如果这对于 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
字符串,描述来自pyppeteer.connection.CDPSession
记录器的响应,而不会污染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 的来源,浏览器页面 object 似乎被埋得很深——所以访问 NetworkManager 并不是很简单。 如果您真的希望它在 requests_html 中工作,那么猴子补丁可能最容易。 这是一个例子:
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()
在 Chrome 中使用 Selenium 也有可能有一个 Python package 用于称为Selenium-interceptor
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.