显示警报时从窗口警报中删除警报文本
Posted
技术标签:
【中文标题】显示警报时从窗口警报中删除警报文本【英文标题】:Scrape alert text from window alert when alert is shown 【发布时间】:2019-11-22 11:04:16 【问题描述】:我正在使用 python 请求库和 BeautifulSoup。
当请求无效时,只有一个 URL 会返回 html 并弹出 alert()
。
Beautifulsoup 中的问题是我无法获得window.alert
弹出文本。
我曾尝试使用this answer 中的正则表达式方法,但它似乎不起作用。
所以当做:
for script in soup.find_all("script"):
alert = re.findall(r'(?<=alert\(\").+(?=\")', script.text)
脚本永远不会得到执行的脚本。
这是我正在提取的脚本:
<script language="javascript">
if(top.frames.length != 0)
location.href="frame_break.jsp"
</script>
<html>
<body>
</body>
</html>
<script>
var err='User ID';
alert(err);
iBankForm.action='login.jsp';
iBankForm.submit();
</script>
我希望收到User ID
的警报文本。
我注意到我是否有无法在下面抓取脚本的标签
如果我将脚本删除或移动到正文标签中,那么我可以获得
<script>
var err='User ID';
alert(err);
iBankForm.action='login.jsp';
iBankForm.submit();
</script>
【问题讨论】:
相关:***.com/questions/54948405/… @JoaoPereira 这不起作用,因为 html 有多个 @Fozoro 不同,由于编写的 html 的性质,它无法获得警报跨度> 在该答案中,为通过使用 find() 方法找到的脚本调用 extract()。您是否尝试过为循环内的每个脚本实例调用 extract() 函数? 它在 HTML 标签之外,所以不会在汤里。检查 html 并查看是否可以添加环视以隔离正确的 var 【参考方案1】:在您的数据上运行 BeautifulSoup 的 diagnose()
时,我会获得以下信息:
data = '''
<script language="JavaScript">
if(top.frames.length != 0)
location.href="frame_break.jsp"
</script>
<html>
<body>
</body>
</html>
<script>
var err='User ID';
alert(err);
iBankForm.action='login.jsp';
iBankForm.submit();
</script>'''
from bs4.diagnose import diagnose
diagnose(data)
打印:
Diagnostic running on Beautiful Soup 4.7.1
Python version 3.6.8 (default, Jan 14 2019, 11:02:34)
[GCC 8.0.1 20180414 (experimental) [trunk revision 259383]]
Found lxml version 4.3.3.0
Found html5lib version 1.0.1
Trying to parse your markup with html.parser
Here's what html.parser did with the markup:
<script language="JavaScript">
if(top.frames.length != 0)
location.href="frame_break.jsp"
</script>
<html>
<body>
</body>
</html>
<script>
var err='User ID';
alert(err);
iBankForm.action='login.jsp';
iBankForm.submit();
</script>
--------------------------------------------------------------------------------
Trying to parse your markup with html5lib
Here's what html5lib did with the markup:
<html>
<head>
<script language="JavaScript">
if(top.frames.length != 0)
location.href="frame_break.jsp"
</script>
</head>
<body>
<script>
var err='User ID';
alert(err);
iBankForm.action='login.jsp';
iBankForm.submit();
</script>
</body>
</html>
--------------------------------------------------------------------------------
Trying to parse your markup with lxml
Here's what lxml did with the markup:
<html>
<head>
<script language="JavaScript">
if(top.frames.length != 0)
location.href="frame_break.jsp"
</script>
</head>
<body>
</body>
</html>
--------------------------------------------------------------------------------
Trying to parse your markup with lxml-xml
Here's what lxml-xml did with the markup:
<?xml version="1.0" encoding="utf-8"?>
<script language="JavaScript">
if(top.frames.length != 0)
location.href="frame_break.jsp"
</script>
--------------------------------------------------------------------------------
由此我可以看到,lxml
解析器不会解析最后一个 <script>
,因此您永远无法通过 BeautifulSoup 访问它。解决方案是不同的解析器,例如html.parser
:
import re
from bs4 import BeautifulSoup
soup = BeautifulSoup(data, 'html.parser')
for script in soup.select('script:contains(alert)'):
alert = re.findall(r'(?<=alert\().+(?=\))', script.text)
print(alert)
打印:
['err']
【讨论】:
【参考方案2】:使用html5lib
解析器库解决
如果您阅读文档https://www.crummy.com/software/BeautifulSoup/bs4/doc/,它会以与 Web 浏览器相同的方式解析页面
这样就可以在body标签之外获取脚本了
soup = BeautifulSoup(payload, 'html5lib')
errors = None
for scr in soup.find_all("script"):
scrExtract = scr.extract()
alert = re.findall('err="(.*\w)', scrExtract.text)
if len(alert) > 0:
errors = alert[0]
print(errors)
【讨论】:
以上是关于显示警报时从窗口警报中删除警报文本的主要内容,如果未能解决你的问题,请参考以下文章
依次显示两个相同的警报视图。如何区分来自警报 1 和警报 2 的文本?
如何在删除时在甜蜜警报弹出窗口中进行 axios 调用并在弹出窗口内的下拉列表中显示数据?