2 回答
TA贡献2012条经验 获得超12个赞
from bs4 import BeautifulSoup as bs
import re
txt = """<div class="buttons_zoom"><div class="full_prod"><a href="javascript:void(0)" onclick="js:getProdID('https://www.XXXXXXX.co.il','{31F93B1D-449F-4AD7-BFB0-97A0A8E068F6}','379104')" title="לחם אחיד פרוס אנג'ל 750 גרם - פרטים נוספים"><img alt="פרטים נוספים" border="0" src="template/images/new_site/icon-view-prod-cartpage.png"/></a></div></div>"""
soup = bs(txt,'html.parser')
a = soup.find("a", attrs={"href":"javascript:void(0)"})
r = re.search(".*'(\d+)'.*", data).groups()[0]
print(r) # will print '379104'
编辑
替换".*\}.*,.*'(\d+)'\).*"
为".*'(\d+)'.*"
. 它们产生相同的结果,但后者更干净。
解释: 汤
find
带有a
标记的(第一个)元素,其中属性“href”的值是“javascript:void(0)”。更多关于美丽的汤关键字参数在这里。
a = soup.find("a", attrs={"href":"javascript:void(0)"})
这相当于
a = soup.find("a", href="javascript:void(0)")
在没有 class_ 快捷方式的旧版本 Beautiful Soup 中,您可以使用上面提到的 attrs 技巧。创建一个字典,其“class”的值是您要搜索的字符串(或正则表达式或其他)。--查看关于“attrs”的漂亮汤文档
a
指向一个类型为 的元素<class 'bs4.element.Tag'>
。我们可以像通过属性访问字典一样访问标签属性a.attrs
(更多关于美丽的汤属性)。这就是我们在以下语句中所做的。
a_tag_attributes = a.attrs # that's the dictionary of attributes in question...
字典键以标签属性命名。这里我们有以下键/属性名称:“title”、“href”和“onclick”。
我们可以通过打印它们自己检查一下。
print(a_tag_attributes.keys()) # equivalent to print(a.attrs.keys())
这将输出
dict_keys(['title', 'href', 'onclick']) # those are the attributes names (the keys to our dictionary)
从这里,我们需要获取我们感兴趣的数据。我们数据的关键是“onclick”(它以我们要查找的数据所在的 html 属性命名)。
data = a_tag_attributes["onclick"] # equivalent to data = a.attrs["onclick"]
data
现在包含以下字符串。
"js:getProdID('https://www.XXXXXXX.co.il','{31F93B1D-449F-4AD7-BFB0-97A0A8E068F6}','379104')"
说明:正则表达式
现在我们已经隔离了包含我们想要的数据的部分,我们将只提取我们需要的部分。
我们将通过使用正则表达式来做到这一点(如果您想了解更多关于 Regex 的好东西,这个站点是一个很好的资源)。
要在 Python 中使用正则表达式,我们必须导入 Regex 模块re
。关于这里的“re”模块的更多信息,好东西。
import re
正则表达式让我们搜索匹配模式的字符串。
这里的字符串是我们的数据,模式是".*'(\d+)'.*"
(这也是一个字符串,你可以通过使用双引号来判断)。
您可以将正则表达式视为类固醇上的通配符。您可能熟悉通配符,例如
*.txt
在文件管理器中查找所有文本文件。正则表达式等价物是^.*\.txt$
.
最好阅读有关正则表达式的内容,以进一步了解它的含义。这是一个快速入门,好东西好东西。
这里我们search
为一个字符串。我们将字符串描述为没有或无限多个字符。这些字符后跟一些数字(至少一个)并用单引号括起来。然后我们有更多的字符。
括号用于提取一个组(在正则表达式中称为捕获),我们只捕获数字部分。
通过将正则表达式的一部分放在圆括号或圆括号内,您可以将正则表达式的该部分组合在一起。这允许您将量词应用于整个组或限制对部分正则表达式的更改。
只能使用括号进行分组。方括号定义了一个字符类,而大括号由具有特定限制的量词使用。--使用括号进行分组和捕获
r = re.search(".*'(\d+)'.*", data)
定义符号:
.* 匹配任何字符(行终止符除外),* 表示可以没有或无限多个
' 匹配字符 '
\d+ 匹配至少一位数字(等于 [0-9]);这就是我们捕获的部分
(\d+) 捕获组;这意味着捕获字符串中重复数字的部分,至少使用一个
() 进行捕获,与括号内的模式匹配的部分将被保存。
拍摄的部分(如果有的话)可以在以后与的呼叫接入r.groups()
上的结果re.search
。
这将返回一个元组,其中包含捕获的内容或None
(r
指的是re.search
函数调用的结果)。
在我们的例子中,元组的第一个(也是唯一一个)项目是数字......
captured_group = r.groups()[0] # that's the tuple containing our data (we captured...)
我们现在可以访问位于元组第一个索引处的数据(我们只捕获了一个组)
print(captured_group[0]) # this will print out '379104'
TA贡献1943条经验 获得超7个赞
下面的两种解决方案都假定onclick属性具有规则/一致的结构
如果只能有一个匹配项,则类似于以下内容。
from bs4 import BeautifulSoup as bs
html ='''
<div class="buttons_zoom"><div class="full_prod"><a href="javascript:void(0)" onclick="js:getProdID('https://www.XXXXXXX.co.il','{31F93B1D-449F-4AD7-BFB0-97A0A8E068F6}','379104')" title="לחם אחיד פרוס אנג'ל 750 גרם - פרטים נוספים"><img alt="פרטים נוספים" border="0" src="template/images/new_site/icon-view-prod-cartpage.png"/></a></div></div>
'''
soup = bs(html, 'lxml')
element = soup.select_one('[onclick^="js:getProdID"]')
print(element['onclick'].split(',')[2].strip(')'))
如果不止一场比赛
from bs4 import BeautifulSoup as bs
html ='''
<div class="buttons_zoom"><div class="full_prod"><a href="javascript:void(0)" onclick="js:getProdID('https://www.XXXXXXX.co.il','{31F93B1D-449F-4AD7-BFB0-97A0A8E068F6}','379104')" title="לחם אחיד פרוס אנג'ל 750 גרם - פרטים נוספים"><img alt="פרטים נוספים" border="0" src="template/images/new_site/icon-view-prod-cartpage.png"/></a></div></div>
'''
soup = bs(html, 'lxml')
elements = soup.select('[onclick^="js:getProdID"]')
for element in elements:
print(element['onclick'].split(',')[2].strip(')'))
- 2 回答
- 0 关注
- 251 浏览
添加回答
举报