gpt4 book ai didi

python - 如何在 Python 中使用 Beautifulsoup 从 HTML 中提取标签

转载 作者:可可西里 更新时间:2023-11-01 13:36:47 25 4
gpt4 key购买 nike

我正在尝试通过简化的 HTML 页面进行解析,如下所示:

<div class="anotherclass part"
<a href="http://example.com" >
<div class="column abc"><strike>&#163;3.99</strike><br>&#163;3.59</div>
<div class="column def"></div>
<div class="column ghi">1 Feb 2013</div>
<div class="column jkl">
<h4>A title</h4>
<p>
<img class="image" src="http://example.com/image.jpg">A, List, Of, Terms, To, Extract - 1 Feb 2013</p>
</div>
</a>
</div>

我是 Python 编码的初学者,我已经阅读并重新阅读了 http://www.crummy.com/software/BeautifulSoup/bs3/documentation.html 上的 beautifulsoup 文档。

我有这个代码:

from BeautifulSoup import BeautifulSoup

with open("file.html") as fp:
html = fp.read()

soup = BeautifulSoup(html)

parts = soup.findAll('a', attrs={"class":re.compile('part'), re.IGNORECASE} )
for part in parts:
mypart={}

# ghi
mypart['ghi'] = part.find(attrs={"class": re.compile('ghi')} ).string
# def
mypart['def'] = part.find(attrs={"class": re.compile('def')} ).string
# h4
mypart['title'] = part.find('h4').string

# jkl
mypart['other'] = part.find('p').string

# abc
pattern = re.compile( r'\&\#163\;(\d{1,}\.?\d{2}?)' )
theprices = re.findall( pattern, str(part) )
if len(theprices) == 2:
mypart['price'] = theprices[1]
mypart['rrp'] = theprices[0]
elif len(theprices) == 1:
mypart['price'] = theprices[0]
mypart['rrp'] = theprices[0]
else:
mypart['price'] = None
mypart['rrp'] = None

我想从类 defghi 中提取我认为我的脚本正确执行的任何文本。

我还想从 abc 中提取两个价格,目前我的脚本以一种相当笨拙的方式进行。这部分有时有两个价格,有时有一个价格,有时没有。

最后,我想从 jkl 类中提取 "A, List, Of, Terms, To, Extract" 部分,我的脚本无法做到这一点。我认为获取 p 标记的字符串部分会起作用,但我不明白为什么它不起作用。这部分中的日期始终与 ghi 类中的日期匹配,因此应该很容易替换/删除它。

有什么建议吗?谢谢!

最佳答案

首先,如果您添加 convertEntities=bs.BeautifulSoup.HTML_ENTITIES

soup = bs.BeautifulSoup(html, convertEntities=bs.BeautifulSoup.HTML_ENTITIES)

然后是 html 实体,例如 &#163;会被转换成它们对应的unicode字符,比如£ .这将允许您使用更简单的正则表达式来识别价格。


现在,给定part ,您可以在<div>中找到文字内容价格使用其 contents属性:

In [37]: part.find(attrs={"class": re.compile('abc')}).contents
Out[37]: [<strike>£3.99</strike>, <br />, u'\xa33.59']

我们需要做的就是从每个项目中提取数字,如果没有数字则跳过:

def parse_price(text):
try:
return float(re.search(r'\d*\.\d+', text).group())
except (TypeError, ValueError, AttributeError):
return None

price = []
for item in part.find(attrs={"class": re.compile('abc')}).contents:
item = parse_price(item.string)
if item:
price.append(item)

此时price将是 0、1 或 2 个 float 的列表。我们想说

mypart['rrp'], mypart['price'] = price

但是如果 price 那将不起作用是[]或仅包含一项。

你用 if..else 处理这三种情况的方法没关系——这是最直接且可以说是最易读的方法。但它也有点平凡。如果您想要更简洁的内容,可以执行以下操作:

如果price,我们想重复相同的价格仅包含一项,您可能会想到 itertools.cycle .

price 的情况下是空列表,[] ,我们想要 itertools.cycle([None]) ,否则我们可以使用 itertools.cycle(price) .

所以要将两种情况组合成一个表达式,我们可以使用

price = itertools.cycle(price or [None])
mypart['rrp'], mypart['price'] = next(price), next(price)

next函数剥离迭代器中的值 price逐个。自 price循环通过它的值(value)观,它永远不会结束;它只会继续按顺序产生值,然后在必要时重新开始——这正是我们想要的。


A, List, Of, Terms, To, Extract - 1 Feb 2013可以通过使用 contents 再次获得属性:

# jkl
mypart['other'] = [item for item in part.find('p').contents
if not isinstance(item, bs.Tag) and item.string.strip()]

因此,完整的可运行代码如下所示:

import BeautifulSoup as bs
import os
import re
import itertools as IT

def parse_price(text):
try:
return float(re.search(r'\d*\.\d+', text).group())
except (TypeError, ValueError, AttributeError):
return None

filename = os.path.expanduser("~/tmp/file.html")
with open(filename) as fp:
html = fp.read()

soup = bs.BeautifulSoup(html, convertEntities=bs.BeautifulSoup.HTML_ENTITIES)

for part in soup.findAll('div', attrs={"class": re.compile('(?i)part')}):
mypart = {}
# abc
price = []
for item in part.find(attrs={"class": re.compile('abc')}).contents:
item = parse_price(item.string)
if item:
price.append(item)

price = IT.cycle(price or [None])
mypart['rrp'], mypart['price'] = next(price), next(price)

# jkl
mypart['other'] = [item for item in part.find('p').contents
if not isinstance(item, bs.Tag) and item.string.strip()]

print(mypart)

产生

{'price': 3.59, 'other': [u'A, List, Of, Terms, To, Extract - 1 Feb 2013'], 'rrp': 3.99}

关于python - 如何在 Python 中使用 Beautifulsoup 从 HTML 中提取标签,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14661368/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com