3

如何使用 python beautifulsoup 解析以下代码?我需要获取每个图像及其相应的宽度和高度属性(如果它们存在)。

下面的代码“表示此页面上有 3 张图片,第一张图片为 300x300,中间一张的尺寸未指定,最后一张为 1000px 高”(如此所述)

<meta property="og:image" content="http://example.com/rock.jpg" />
<meta property="og:image:width" content="300" />
<meta property="og:image:height" content="300" />
<meta property="og:image" content="http://example.com/rock2.jpg" />
<meta property="og:image" content="http://example.com/rock3.jpg" />
<meta property="og:image:height" content="1000" />

到目前为止,我有以下代码,但它只返回第一组维度:

images = []
img_list = soup.findAll('meta', {"property":'og:image'})
for og_image in img_list:
    if not og_image.get('content'):
        continue

    image = {'url': og_image['content']}

    width = self.soup.find('meta', {"property":'og:image:width'})
    if width:
        image['width'] = width['content']
    height = self.soup.find('meta', {"property":'og:image:height'})
    if width:
        image['height'] = height['content']

    images.append(image)

谢谢!

4

3 回答 3

2

这不是 BeautifulSoup,但 pyparsing 方法可以很快组合在一起:

html = """
<meta property="og:image" content="http://example.com/rock.jpg" /> 
<meta property="og:image:width" content="300" /> 
<meta property="og:image:height" content="300" /> 
<meta property="og:image" content="http://example.com/rock2.jpg" /> 
<meta property="og:image" content="http://example.com/rock3.jpg" /> 
<meta property="og:image:height" content="1000" /> 
"""

from pyparsing import makeHTMLTags, withAttribute, Optional, Group

# use makeHTMLTags to define tag expressions (allows attributes, whitespace, 
# closing '/', etc., and sets up results names for matched attributes so they
# are easy to get at later)
meta,metaEnd = makeHTMLTags("meta")

# define a copy of the opening tag, filtering on the specific attribute to select for
img_meta = meta.copy().setParseAction(withAttribute(('property','og:image')))
wid_meta = meta.copy().setParseAction(withAttribute(('property','og:image:width')))
hgt_meta = meta.copy().setParseAction(withAttribute(('property','og:image:height')))

# now define the overall expression to look for, and assign names for subexpressions
# for width and height
img_ref = img_meta + Optional(Group(wid_meta)("width")) + Optional(Group(hgt_meta)("height"))

# use searchString to scan through the given text looking for matches
for img in img_ref.searchString(html):
    print "IMAGE:", img.content
    if img.height:
        print "H:", img.height.content
    if img.width:
        print "W:", img.width.content
    print

印刷:

IMAGE: http://example.com/rock.jpg
H: 300
W: 300

IMAGE: http://example.com/rock2.jpg

IMAGE: http://example.com/rock3.jpg
H: 1000
于 2012-08-15T09:59:15.340 回答
2

我想要一些快速的东西,它使用beautifulsoup 树结构。这是我认为合适的解决方案,以防有人在寻找类似的东西:

from BeautifulSoup import BeautifulSoup, Tag

soup = BeautifulSoup(html)
images = []
image = {}

img_list = soup.findAll('meta', {"property":'og:image'})
for og_image in img_list:
    if not og_image.get('content'):
        continue

    image = {'url': og_image['content']}
    next = og_image.nextSibling.nextSibling # calling once returns end of line char '\n'

    if next and isinstance(next, Tag) and next.get('property', '').startswith('og:image:'):
        dimension = next['content']
        prop = next.get('property').rsplit(':')[-1]
        image[prop] = dimension

        next = next.nextSibling.nextSibling
        if next and isinstance(next, Tag) and next.get('property', '').startswith('og:image:'):
            dimension = next['content']
            prop = next.get('property').rsplit(':')[-1]
            image[prop] = dimension

    images.append(image)
于 2012-10-01T14:11:36.780 回答
0

你的不是解析问题,而是列表处理问题。你想像这样“分组”一个列表:

[u'http://example.com/rock.jpg', u'300', u'300', u'http://example.com/rock2.jpg', u'http://example.com/rock3.jpg', u'1000']

变成这样:

[[u'http://example.com/rock.jpg', u'300', u'300'], [u'http://example.com/rock2.jpg'], [u'http://example.com/rock3.jpg', u'1000']]

这是我的解决方案:

import BeautifulSoup as BS                                                  


content = '''<meta property="og:image" content="http://example.com/rock.jpg" 
<meta property="og:image:width" content="300" />                            
<meta property="og:image:height" content="300" />                           
<meta property="og:image" content="http://example.com/rock2.jpg" />         
<meta property="og:image" content="http://example.com/rock3.jpg" />         
<meta property="og:image:height" content="1000" />'''                       


soup = BS.BeautifulSoup(content)                                            
data = [m['content'] for m in soup.findAll('meta')]                         

# Grouping                                                                            
images = []                                                                 
current_image = None                                                        
for d in data:                                                              
    if d.startswith('http'):                                                
        if current_image:                                                   
            images.append(current_image)                                    
        current_image = [d]                                                 
    else:                                                                   
        if current_image:                                                   
            current_image.append(d)                                         
        else:                                                               
            raise Exception('error')                                        
images.append(current_image)                                                

print data                                                                  
print images                                                                
于 2012-08-15T10:09:52.077 回答