从 HTML 中的脚本元素中提取对象键的值
Extracting a value of an object key from inside the script element in the HTML
<div class="heading-dom view">
<script type="application/javascript">
window.realty = {"user_id":4243456};
<!--window.agency = < %- JSON.stringify(agency) % >;-->
<!--window.agency = < %- JSON.stringify({}) % >-->
</script>
</div>
我想要的输出是 4243456
。我如何使用 beautifulsoup 的 lxml 提取它?
您可以使用 BeautifulSoup 提取脚本标签的文本,但为了获得 user_id
您需要使用正则表达式
# Assuming it's the only number in the script's text
pattern = re.compile('\d+')
soup = BeautifulSoup(page, 'lxml')
for i in soup.select('script'):
print(re.findall(pattern, i.text))
输出
['4243456']
这总体上是一个有趣的问题 - 从 HTML 代码中的 JavaScript 代码中提取内容。
基本上,这意味着您首先需要进行 HTML 解析 - 找到所需的 script
元素并获取其文本。然后,第二步是从 realty
对象中提取所需的数字。
如果您想要使用正则表达式方法,您实际上可以重新使用正则表达式来定位所需的 script
元素并提取所需的变量(BeautifulSoup
allows to apply regular expression patterns 到 find/filter 的元素):
import re
from bs4 import BeautifulSoup
html = """
<div class="heading-dom view">
<script type="application/javascript">
window.realty = {"user_id":4243456};
<!--window.agency = < %- JSON.stringify(agency) % >;-->
<!--window.agency = < %- JSON.stringify({}) % >-->
</script>
</div>"""
pattern = re.compile(r'\{"user_id"\s*:\s*(\d+)\}')
soup = BeautifulSoup(html, "html.parser")
script = soup.find("script", text=pattern)
print(pattern.search(script.text).group(1))
# prints 4243456
让我们在这里分解\{"user_id"\s*:\s*(\d+)\}
:
- 反斜杠用于转义在正则表达式语法中具有特殊含义的字符
\s*
表示 - 零个或多个 space 字符(把它放在那里以防万一你在对象定义中的 :
周围有额外的 space )
\d+
表示"one or more digits"
- 括号定义一个 capturing group - 这是我们将字符串的特定部分提取到一个组中的方法,然后我们通过
.group(1)
访问该组
请注意,@Evyatar 建议的简单 \d+
表达式过于宽泛,您可能很容易得到误报。
以下是一些类似的主题,其中还包含一些其他选项:
- Extracting text from script tag using BeautifulSoup in Python
如果您想避免使用 regex
:
,可以选择字符串操作
from bs4 import BeautifulSoup
content='''
<div class="heading-dom view">
<script type="application/javascript">
window.realty = {"user_id":4243456};
<!--window.agency = < %- JSON.stringify(agency) % >;-->
<!--window.agency = < %- JSON.stringify({}) % >-->
</script>
</div>
'''
soup = BeautifulSoup(content,'lxml')
item = soup.select('script')[0].text.split('user_id":')[1].split("}")[0]
print(item)
输出:
4243456
<div class="heading-dom view">
<script type="application/javascript">
window.realty = {"user_id":4243456};
<!--window.agency = < %- JSON.stringify(agency) % >;-->
<!--window.agency = < %- JSON.stringify({}) % >-->
</script>
</div>
我想要的输出是 4243456
。我如何使用 beautifulsoup 的 lxml 提取它?
您可以使用 BeautifulSoup 提取脚本标签的文本,但为了获得 user_id
您需要使用正则表达式
# Assuming it's the only number in the script's text
pattern = re.compile('\d+')
soup = BeautifulSoup(page, 'lxml')
for i in soup.select('script'):
print(re.findall(pattern, i.text))
输出
['4243456']
这总体上是一个有趣的问题 - 从 HTML 代码中的 JavaScript 代码中提取内容。
基本上,这意味着您首先需要进行 HTML 解析 - 找到所需的 script
元素并获取其文本。然后,第二步是从 realty
对象中提取所需的数字。
如果您想要使用正则表达式方法,您实际上可以重新使用正则表达式来定位所需的 script
元素并提取所需的变量(BeautifulSoup
allows to apply regular expression patterns 到 find/filter 的元素):
import re
from bs4 import BeautifulSoup
html = """
<div class="heading-dom view">
<script type="application/javascript">
window.realty = {"user_id":4243456};
<!--window.agency = < %- JSON.stringify(agency) % >;-->
<!--window.agency = < %- JSON.stringify({}) % >-->
</script>
</div>"""
pattern = re.compile(r'\{"user_id"\s*:\s*(\d+)\}')
soup = BeautifulSoup(html, "html.parser")
script = soup.find("script", text=pattern)
print(pattern.search(script.text).group(1))
# prints 4243456
让我们在这里分解\{"user_id"\s*:\s*(\d+)\}
:
- 反斜杠用于转义在正则表达式语法中具有特殊含义的字符
\s*
表示 - 零个或多个 space 字符(把它放在那里以防万一你在对象定义中的:
周围有额外的 space )\d+
表示"one or more digits"- 括号定义一个 capturing group - 这是我们将字符串的特定部分提取到一个组中的方法,然后我们通过
.group(1)
访问该组
请注意,@Evyatar 建议的简单 \d+
表达式过于宽泛,您可能很容易得到误报。
以下是一些类似的主题,其中还包含一些其他选项:
- Extracting text from script tag using BeautifulSoup in Python
如果您想避免使用 regex
:
from bs4 import BeautifulSoup
content='''
<div class="heading-dom view">
<script type="application/javascript">
window.realty = {"user_id":4243456};
<!--window.agency = < %- JSON.stringify(agency) % >;-->
<!--window.agency = < %- JSON.stringify({}) % >-->
</script>
</div>
'''
soup = BeautifulSoup(content,'lxml')
item = soup.select('script')[0].text.split('user_id":')[1].split("}")[0]
print(item)
输出:
4243456