为了账号安全,请及时绑定邮箱和手机立即绑定

使用 python beautifulsoup 从 html 中获取指定值

使用 python beautifulsoup 从 html 中获取指定值

Go
GCT1015 2021-11-16 09:44:17
我是报废的新手,我正在做一些报废项目,我试图从下面的 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>我想得到这个值:379104 位于 onclick im 中使用 BeautifulSoup 代码: for i in page_content.find_all('div', attrs={'class':'prodPrice'}):            temp = i.parent.parent.contents[0]temp 返回对象列表和 temp= 到 Html 上面有人可以帮助提取这个 id 谢谢!!编辑****** 哇伙计们感谢惊人的解释!!!!!! 但我有 2 个问题 1.retry 机制没有工作我将其设置为 timeout=1 以使其失败,但一旦失败则返回:requests.exceptions.RetryError: HTTPSConnectionPool(host='www.XXXXX.il', port=443): Max retries exceeded with url: /default.asp?catid=%7B2234C62C-BD68-4641-ABF4-3C225D7E3D81%7D (Caused by ResponseError('too many redirects',)) 你能帮我解决下面的重试机制代码吗: 2. 当我设置超时=6 8000 个项目的报废持续时间为 15 分钟时,没有重试机制的性能问题我如何提高此代码的性能?代码如下:def get_items(self, dict):        itemdict = {}        for k, v in dict.items():            boolean = True        # here, we fetch the content from the url, using the requests library            while (boolean):             try:                a =requests.Session()                retries = Retry(total=3, backoff_factor=0.1, status_forcelist=[301,500, 502, 503, 504])                a.mount(('https://'), HTTPAdapter(max_retries=retries))                page_response = a.get('https://www.XXXXXXX.il' + v, timeout=1)             except requests.exceptions.Timeout:                print  ("Timeout occurred")                logging.basicConfig(level=logging.DEBUG)             else:                 boolean = False
查看完整描述

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'


查看完整回答
反对 回复 2021-11-16
?
杨__羊羊

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(')'))


查看完整回答
反对 回复 2021-11-16
  • 2 回答
  • 0 关注
  • 251 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信